Treap

  所谓Treap,就是单词Tree和heap的合成词,它是具有堆特性的一颗二叉查找树,它和 笛卡尔树(Cartesian Tree)的形式很像。因为当二叉查找树退化时速度会很满,所以引入了随机优先值的heap,使在Treap树中,根节点的值大于等于左子树的值,小于等于右子树的值,根节点的优先值大于子树的优先值(其实这里优先值纯属个人喜好,大于和小于效果一样)。如下图所示(黑色为权值,红色为优先值):
  Treap
  存储Treap的结构如下:

type treap = record
               rnd,val,size,w:longint; 
               //分别是优先值,权值,以当前节点为根子节点的个数,和当前节点权值相同的个数
               l,r:longint;     
               //分别记录左儿子和右儿子编号,0为空
             end;
var tree:array[0..MAXN] of treap;

1.插入(期望复杂度为 O(log2n) ):
  1.按照二叉查找树的方式插入
  2.根据优先值进行旋转调整

  代码如下(tot为总节点个数): 

procedure insert(var k:longint; x:longint);
  begin
    if k=0 then begin
      inc(tot); k:=tot;
      tree[k].size:=1; tree[k].w:=1
      tree[k].val:=x; tree[k].rnd:=random(MAXD);
      tree[k].l:=0; tree[k].r:=0;
      exit;
    end;
    inc(tree[k].size); 
    if tree[k].val=x then begin inc(tree[k].w); exit; end;
    if x<tree[k].val then begin
      insert(tree[k].l,x);
      if tree[tree[k].l].rnd>tree[k].rnd then right_rotation(k);
      exit;
    end;
    if x>tree[k].val then begin
      insert(tree[k].r,x);
      if tree[tree[k].r].rnd>tree[k].rnd then left_rotation(k);
  end;

  在插入我们看到进行了两种旋转操作,分别是左旋left_rotation和右旋right_rotation:左旋和右旋
  实现代码如下:

procedure left_rotation(var k:longint);
   var tmp:longint;
   begin
     tmp:=tree[k].r; tree[k].r:=tree[tmp].l; tree[tmp].l:=k;
     update(k); update(tmp); k:=tmp;
   end;
procedure right_rotation(var k:longint);
   var tmp:longint;
   begin
     tmp:=tree[k].l; tree[k].l:=tree[tmp].r; tree[tmp].r:=k;
     update(k); update(tmp); k:=tmp;
   end;

  注意到过程中有一个新的函数update,因为我们刚刚只完成了旋转,节点上的数据还需要改变:

procedure update(k:longint);
  begin
    tree[k].size:=tree[tree[k].l].size+tree[tree[k].r].size+tree[k].w;
  end;

  这样插入操作就完成了。

2.删除(期望复杂度为 O(log2n)
  1.找到要删除的点的位置
  2.将其向下旋转至只有一个儿子或为叶子节点时进行删除
  
  实现代码如下:

procedure delete(var k:longint; x:longint);
  begin
    if k=0 then exit;
    if tree[k].val=x then begin
      if tree[k].w>1 then begin
        dec(tree[k].w); dec(tree[k].size); exit;
      end;
      if tree[k].l*tree[k].r=0 then begin
        k:=tree[k].l+tree[k].r;
      end
      else if tree[tree[k].l].rnd>tree[tree[k].r].rnd 
             then begin
               right_rotation(k); delete(k,x);
             end
             else begin
               left_rotation(k); delete(l,x);
             end;
    end
    else if x>tree[x].val
           then begin
             dec(tree[k].size); delete(tree[k].r,x);
           end
           else begin
             dec(tree[k].size); delete(tree[k].l,x);
           end;
  end;

3.查询
  与二叉查找树相同
  
  代码如下:(查找第x大的数)

function query_num(k,x:longint);  
  begin
    if k=0 then exit;
    if x<=tree[tree[k].l].size]
      then exit(query_num(tree[k].l,x))
      else if (x>tree[tree[k].l].size+tree[k].w)
             then exit(query_num(tree[k].r,x-tree[tree[k].l].size-tree[k].w))
             else exit(tree[k].val);
  end;

4.前驱,后继
  与二叉查找树相同
  
  代码如下:

procedure query_pred(k,x:longint);
  begin
    if k=0 then exit;
    if tree[k].val<x then begin
      ans:=k; query_pred(tree[k].r,x);
    end
    else query_pred(tree[k].l,x);
  end;
procedure query_succ(k,x:longint);
  begin
    if k=0 then exit;
    if tree[k].val>x then begin
      ans:=k; query_pred(tree[k].l,x);
    end
    else query_pred(tree[k].r,x);
  end;

参考资料:
1.Treap_百度百科
2.黄学长blog:HZWER:We are OIers|Hello world!My blog

内容概要:本文详细介绍了在Linux环境下进行C++开发所需掌握的内容,以一个Web多人聊天项目为例,涵盖从开发环境搭建到项目部署的全过程。首先推荐了一个项目地址,该项目支持HTTP请求、Websocket、多房间和多人聊天、MySQL用户信息存储、Redis缓存、json序列化等功能,并建议扩展功能如基于Reactor模型构建HTTP/Websocket服务、仿写MySQL/Redis连接池等。接着介绍了开发环境,包括Ubuntu 20.04、MySQL 8.0、Redis 6.0、gcc/g++ 10.5.0等,并提供了详细的部署步骤,如安装boost库、编译聊天室服务、配置MySQL和Redis等。最后分析了项目架构,包括数据存储(MySQL存储用户信息,Redis存储房间消息和用户cookie)、消息格式(HTTP请求消息和Websocket交互消息)、HTTP/Websocket数据处理流程等。; 适合人群:有一定Linux基础,想深入了解C++开发及网络编程的开发者,尤其是有志于从事Web开发或服务器端开发的技术人员。; 使用场景及目标:①掌握Linux C++开发环境的搭建,包括工具链的安装与配置;②理解并实践HTTP、Websocket等网络协议的应用;③熟悉MySQL、Redis等数据库的使用;④学习如何处理HTTP请求、Websocket交互消息及数据存储;⑤能够独立完成类似Web聊天室的项目开发。; 其他说明:本文不仅提供了理论指导,还给出了具体的实践操作步骤,如编译过程中可能遇到的问题及解决方案。对于初学者来说,可以按照文中提供的链接和教程逐步学习,同时鼓励读者根据自身需求对项目进行扩展和优化。
【文章/演示视频链接:https://archie.blog.youkuaiyun.com/article/details/147283872?spm=1001.2014.3001.5502】1.本系统有一个主机,两个从机。2.一主多从的LORA组网通信,主机和两个从机都配备了STM32F103单片机与 LoRa 模块,主机作为中心设备及WIFI网关,负责接收和发送数据到远程物联网平台和手机APP,两个从机则负责采集数据并通过各自的 LoRa组网将数据发送给主机。3.两个LORA从机,功能一样,组网分别实现对温度、湿度、粉尘PM2.5、PM10、CO2和NH3进行实时采集,并在OLED显示屏显示,系统采用锂电池供电。从机所用主要硬件:STM32F103C8T6最小系统板、多合一环境检测模组、0.96寸OLED显示屏、MQ-135传感器、正点原子LORA模块ATK-LORA-01、18650锂电池。4.主机LORA,组网实现接收两个从机采集过来的数据,通过主机WIFI模块网关将两个从机的数据远程传输到物联网云服务器和手机APP。主机所用主要硬件:STM32F103C8T6最小系统板、ESP8266模块、正点原子LORA模块ATK-LORA-01、18650锂电池。 资料包,包含本项目所有的程序源码和原理图 1.程序源码文件如下所示: “0.机智云MCU代码生成”是机智云平台生成的代码 “1.主机-未移入机智云”是没有移植机智云的代码(方便更改为你的机智云) “1.主机-移入机智云-此程序可接入机智云”是本项目的主机网关程序 “2.从机1-本地数据采集与显示”是本项目的从机1程序 “3.从机2-本地数据采集与显示”是本项目的从机2程序 【物联网】基于LORA组网的远程环境监测系统设计(资料包)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值