<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      Fork me on GitHub

      堆堆的世界

      可并堆

      可并堆有三種常見方法:斜堆,左偏樹,隨機堆我們分別聊聊這三種堆吧!

      斜堆

      斜堆的構建其實是和二叉堆差不多的,它只是用鏈表來維護關系罷了,這是構建代碼:

      struct Heap
      {
          Heap *lson, *rson;
          int val;
          Heap(int n = 0)
          {
              val = n;
              lson = rson = 0;
          }
      };
      

      然后,可并堆可并堆,最重要的是合并吧,合并怎么做呢,就是假設有兩個斜堆,將其權值比較大的斜堆插在權值比較小的斜堆的右子樹之下,但是如果只這樣的話,時間復雜度就會退化到 \(O(n)\) 的,我們只要將左子樹和右子樹交換一下 這樣子的左右子樹就比較均勻啦!,時間復雜度就講到 \(O(log_n)\) 啦,代碼如下:

      Heap* merge(Heap*& a, Heap*& b)
      {
          if(a == 0) return a;
          if(b == 0) return b;
          if(a -> val > b -> val) swap(a, b);
          a -> rson = merge(a -> rson, b);
          swap(a -> lson, a -> rson);
          return a;
      }
      

      剩下的就和二叉堆差不多了,代碼如下:

      void Heap_insert(Heap*& a, int val)//插入
      {
          Heap* b = new Heap(val);
          a = merge(a, b);
      }
      
      int Top(Heap*& a)//求最小
      {
          int val = a -> val;
          return val;
      }
      
      void Del(Heap*& a)//刪最小
      {
          a = merge(a -> lson, a -> rson);
      }
      

      紅黑樹和隨機堆就沒有那么簡單了。

      你會發現,雖然你將左子樹和右子樹調換了從而減少了常數,但是你沒法保證這調換完之后一定左子樹比右子樹來的重呀,所以還是時間復雜度很大滴,但是欸,我們可以存一個值,表示該子樹的大小呀,這不就好了嘛。。所以,左偏樹誕生了!

      左偏樹

      基本結構與斜堆一樣,只是左偏樹的每個結點多了一個距離值NPL即該結點一直向右兒子走,到達空結點的距離。
      構建還是和斜堆很像,代碼如下:

      struct Heap
      {
          Heap* lson;
          Heap* rson;
          int VAL, npl;
          Heap(int n = 0)
          {
              val = n;
              npl = 1;
              lson = 0;
              rson = 0;
          }
      };
      

      接下來依然是合并,維護了 \(npl\) 之后,我們就不用再亂交換了,而且保證了左兒子大于右兒子的\(npl\) ,效率就會提升。

      那么怎么維護 \(npl\) 呢?我們來看看新的\(Merge\)

      Heap* Merge(Heap*& a, Heap*& b)
      {
      	if(a == 0) return b;
      	if(b == 0) return a;
      	if(a -> val > b -> val) swap(a, b);
      	a -> rson = Merge(a -> rson, b);
      	if(!a -> lson || a -> lson -> npl < a -> rson -> npl) swap(a -> lson, a -> rson);
      	if(!a -> rson) a -> npl=0;
      	else a -> npl = a -> rson -> npl + 1;
      	return a;
      }
      

      下面是注解
      首先,如果左右子樹為空,直接返回另一個
      第二,如果左子樹的 \(npl\) 比較小,交換后使右子樹的高度變小,再合并。
      合并后維護 \(npl\),如果右子樹為空,\(npl\)\(0\),否則為右子樹的 \(npl++\)

      剩下的就都差不多了,代碼如下:

      void Heap_insert(Heap*& root,int k)
      {
      	Heap* n = new Heap(k);
      	root = Merge(root,n);
      }
      int Top(Heap*& root)
      {
      	return root -> val;
      }
      void del(Heap*& root)
      {
      	root = Merge(root -> lson, root -> rson);
      }
      

      隨機堆

      其實我們有另一種方法,欸,就是隨機,我們可以通過隨機數的奇偶來決定這次要不要交換,這樣子的話就能比一直交換的常數來的小,剩下的重要點前面都已經講過啦!所以就只放全部代碼了:

      struct Heap
      {
      	Heap* lson;
      	Heap* rson;
      	int val;
      	Heap(int n = 0)
      	{
      		val = n;
      		lson = 0;
      		rson = 0;
      	}
      }*root;
      
      Heap* Merge(Heap*& a,Heap*& b)
      {
      	if(a == 0) return b;
      	if(b == 0) return a;
      	if(a -> val > b -> val) swap(a,b);
      	if(rand() & 1) a -> rson = Merge(a -> rson, b);
      	else a -> lson = Merge(a -> lson, b);
      	return a;
      }
      void Heap_insert(Heap*& root,int k)
      {
      	Heap* n = new Heap(k);
      	root = Merge(root, n);
      }
      
      int Top(Heap*& root)
      {
      	return root -> val;
      }
      
      void del(RandHeap*& root)
      {
      	root = Merge(root -> lson, root -> rson);
      }
      

      我這里用的是 \(rand()\) 常數超級大,大家可以換成其他的隨機數生成方式。

      小結

      這三種可并堆的優缺點各不相同,雖然普遍都是用左偏樹,但是其他的也要學呀,要不然他為什么要存在呢?


      例題

      # P11833 [省選聯考 2025] 推箱子

      呃,就直接放個用可并堆打的的文章吧,在這

      還有關于題單,找了好久,終于在半個月后找到了。。。。

      posted @ 2025-06-04 15:12  tony0530  閱讀(16)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产欧美亚洲精品a第一页| 获嘉县| 国内自拍小视频在线看| 国色精品卡一卡2卡3卡4卡在线 | 五月丁香综合缴情六月小说| 狠狠综合久久综合88亚洲| 亚洲国产欧美在线看片一国产| 风流少妇又紧又爽又丰满| 蜜臀av一区二区精品字幕| 少妇真人直播免费视频| 日本精品成人一区二区三区视频| 亚洲人成网站免费播放| 亚洲精品乱码久久久久久中文字幕| 狠狠cao日日穞夜夜穞av| 九九综合va免费看| 黑色丝袜脚交视频麻豆| 亚洲精品韩国一区二区| 久久国产精品精品国产色| japanese无码中文字幕| 精品一区二区三人妻视频| 777奇米四色成人影视色区| 337p日本欧洲亚洲大胆色噜噜 | 亚洲aⅴ天堂av天堂无码麻豆| 性欧美老人牲交xxxxx视频 | 亚洲精品中文字幕码专区| 久久88香港三级台湾三级播放| yw尤物av无码国产在线观看| 精品一区二区三区在线视频观看| 亚洲AV成人片不卡无码| 久久不见久久见免费视频观看| 亚洲AV无码久久久久网站蜜桃| 欧美老少配性行为| 99精品国产精品一区二区| 国产在线永久视频| 波多野结衣在线精品视频| 秋霞av鲁丝片一区二区| 无码专区人妻系列日韩精品| 国产97人人超碰CAO蜜芽PROM| 亚洲欧美日韩国产精品专区| 久久精品久久精品久久精品 | 国产一区二区高清不卡|