青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆-163  評論-223  文章-30  trackbacks-0
前言
   眾所周知,stl中的優先級隊列是基于最大堆實現的,能夠在對數時間內插入元素和獲取優先級最高的元素,但如果要求在對數時間內還能獲取優先級最低的元素,而不只是獲取優先級最高的元素,該怎么實現呢?可以用最大堆-最小堆或雙端堆數據結構來實現,最大堆-最小堆和雙端堆都是支持雙端優先隊列的插入、刪除最小元素和最大元素等操作的堆,在這些操作上,時間復雜度都是對數時間,但是雙端堆的操作比最大堆-最小堆的相應操作還要快一個常數因子,而且算法更加簡單,因此本文講述選擇使用雙端堆實現優先級隊列的原理。

定義與性質
   雙端堆是一顆完全二叉樹,該完全二叉樹要么為空,要么滿足以下性質:
 (1)根結點不包含元素
 (2)左子樹是一個最小堆
 (3)右子樹是一個最大堆
 (4)如果右子樹不為空,則令i是左子樹中任一結點,j是i在右子樹中的對應結點,如果i在右子樹中的對應結點不存在,則j為i的父結點在右子樹中的對應結點,  對于結點i和j,i的關鍵字值小于等于j的關鍵字值。
   從以上性質可以推出:對于左子結中的任一結點i,設j為i的對稱結點,則由最小元素到i,i到j,j到最大元素的路徑上元素是非遞減有序的。在雙端堆上的操作算法核心就是為了保證這樣的單向路徑上元素必須是非遞減有序的。
   例如下圖所示,就是一個雙端堆
操作算法
 (1)插入元素:設所插結點為i,其對稱結點為j,要分2種情況 a)當i處于最小堆時,則j處于最大堆中,如果KeyValue(i)>KeyValue(j),則設置value= KeyValue(i),KeyValue(i)=KeyValue(j),并執行在最大堆中位置j處插入值value的操作;否則執行在最小堆中位置i處插入值KeyValue(i)的操作。b)當i處于最大堆時,則j處于最小堆中,如果KeyValue(i)<KeyValue(j),則設置value=KeyValue(i),KeyValue(i)=KeyVaue(j),并執行在最小堆中位置i處插入值value的操作;否則執行在最大堆中位置j處插入值KeyValue(i)的操作。

 (2)刪除最小元素:首先在最小堆中執行一個向下回溯過程,這個過程執行的堆大小要比原來的堆小1,從最小元素結點開始,每次選取關鍵字值較小的孩子結點,并用其值更新父結點值,直到底部沒有孩子結點,執行的結果是在底部某葉子結點i處形成一個空洞(形象說法,這個空洞需要后續操作來調整填補,下同),i的對稱結點j在最大堆中,設最末元素結點為e,如果KeyValue(e)>KeyValue(j),則設置KeyValue(i)=KeyValue(j),并執行在最大堆中位置j處插入值KeyValue(e)的操作;否則執行在最小堆中位置i處插入值KeyValue(e)的操作。

 (3)刪除最大元素:這個操作比刪除最小元素要麻煩一點,和刪除最小元素類似,先執行一個向下回溯過程得到空洞結點i,其對稱結點為j,為了保證能滿足雙端堆的性質,需要考慮以下幾種情況:a)j只存在一個孩子,如下圖第1個所示。 b)j存在兩個孩子,如下圖第2個所示。 c)j不存在孩子,但存在左兄弟(可能存在孩子),如下圖第3個所示。 d)j不存在孩子,但存在右兄弟,如下圖最后一個所示。
令min為具有較小值的結點,max為具有較大值的結點,最末元素結點為e,value=KeyValue(e),如果j存在孩子結點,則 min為孩子中關鍵字值較小的結點,max為關鍵字值較大的結點;否則min為j和其兄弟結點中關鍵字值較小的結點,max為關鍵字值較大的結點。如果KeyValue(min)<value而且value<KeyValue(max),在這種情況下,只需調整i或其父結點、max的值即可,操作如下:如果KeyValue(i)<KeyValue(max),則設置KeyValue(parent(i))=KeyValue(max),否則設置KeyValue(i)=KeyValue(max),最后設置KeyValue(max)=value;如果KeyValue(max)<=value,在這種情況下,則執行在最大堆中位置i處插入值value的操作;如果value<=KeyVlaue(min),在這種情況下,先調整i或其父結點、max的值(見上),再執行在最小堆中位置min處插入值value的操作。

 (4)構造堆:給定一個元素大小為N的序列S,在這個序列空間上構造堆,一般有兩種實現方法,一是循環N-1次,每次插入元素S[i],也就是自頂向下構建堆,時間復雜度為O(NlgN)。另一種是從最后一個內部結點N/2左右開始,執行調整堆操作,直到第一個元素,也就是自底向上構建堆,時間復雜度為O(N)。

 (5)最大堆(最小堆)插入:這是一個向上回溯過程,和單個最大堆(最小堆)操作是一樣的,從底部某處開始,比較待插元素和結點關鍵字值大小,直到前者不大于(不小于)后者時或碰到最大堆(最小堆)頂部為止,這時就找到了插入位置,將待插元素放到這個位置即可。

   設雙端堆元素個數為N,由于完全二叉樹高度為O(lgN),則插入元素操作時間復雜度為O(lgN),刪除最小元素和最大元素為不超過2O(lgN),實現這些操作最重要的一點就是要保證性質4,只有當性質4滿足時,雙端堆才有意義,才能保證獲取最大元素和最小元素操作的對數時間,具體的實現詳見下文。
posted on 2011-10-03 17:53 春秋十二月 閱讀(3844) 評論(3)  編輯 收藏 引用 所屬分類: Algorithm

評論:
# re: 基于雙端堆實現的優先級隊列(2): 內幕 2014-01-05 10:06 | Cppowboy
你好,我學習了您講解的算法之后自己按照算法寫了C++的實現,包括插入,刪除最小,刪除最大的操作,但是在線評測總是出問題,個人檢查認為是對的,您能幫忙指點一下,看看哪里錯了嗎?
#include <stdio.h>
#include <cstring>
#include <cmath>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define SIZE 110100

struct heap
{
public:
void init();
void insert(long long);
long long del_min();
long long del_max();

void fool_min_insert(long long,long long);
void fool_max_insert(long long,long long);
void min_push_down(long long&);
void max_push_down(long long&);

long long parent(long long n){return n/2;}
long long lchild(long long n){if(n*2<=size)return 2*n;else return 0;}
long long rchild(long long n){if(n*2+1<=size)return n*2+1;else return 0;}
bool is_min_heap(long long n)
{
while(n>3)n/=2;
if(n==2)return true;
else return false;
}
long long partner(long long n)
{
long long j=log((double)n)/log((double)2);
long long k=(long long)pow((double)2,(double)j)-1;
long long e=k^n;
if(e<=size)return e;
else return partner(parent(n));
}
void swap(long long &a,long long &b){long long temp=a;a=b;b=temp;}
private:
long long key[SIZE];
long long size;
};
void heap::init()
{
size=1;
memset(key,-1,sizeof(key));
}
void heap::fool_min_insert(long long k,long long pos)
{
key[pos]=k;
long long cur=pos;
while(parent(cur)>1)
{
if(key[parent(cur)]>key[cur])
{
swap(key[parent(cur)],key[cur]);
cur=parent(cur);
}
else break;
}
}
void heap::fool_max_insert(long long k,long long pos)
{
key[pos]=k;
long long cur=pos;
while(parent(cur)>1)
{
if(key[parent(cur)]<key[cur])
{
swap(key[parent(cur)],key[cur]);
cur=parent(cur);
}
else break;
}
}
void heap::insert(long long k)
{
size++;
if(size==2)
{
key[size]=k;
return;
}
if(is_min_heap(size))
{
long long j=partner(size);
if(k<=key[j])
fool_min_insert(k,size);
else
{
fool_min_insert(key[j],size);
fool_max_insert(k,j);
}
}
else
{
long long j=partner(size);
if(k>=key[j])
fool_max_insert(k,size);
else
{
fool_max_insert(key[j],size);
fool_min_insert(k,j);
}
}
}
void heap::min_push_down(long long& cur)
{
long long c;
while(lchild(cur)!=0)
{
c=cur;
if(lchild(cur)!=0)c=lchild(cur);
if(rchild(cur)!=0&&key[rchild(cur)]<=key[lchild(cur)])
c=rchild(cur);
key[cur]=key[c];
cur=c;
}
}
void heap::max_push_down(long long& cur)
{
long long c;
while(lchild(cur)!=0)
{
c=cur;
if(lchild(cur)!=0)c=lchild(cur);
if(rchild(cur)!=0&&key[rchild(cur)]>=key[lchild(cur)])
c=rchild(cur);
key[cur]=key[c];
cur=c;
}
}
long long heap::del_min()
{
if(size==1)return 0;
if(size==2)
{
size--;
return key[size+1];
}
long long e=key[2];
long long cur=2;
min_push_down(cur);
long long j=partner(cur);
long long value=key[size];
if(value<=key[j])
fool_min_insert(value,cur);
else
{
fool_min_insert(key[j],cur);
fool_max_insert(value,j);
}
size--;
return e;
}
long long heap::del_max()
{
if(size==1)return 0;
if(size==2)return key[size--];
long long e=key[3];
long long cur=3;
max_push_down(cur);
long long j=partner(cur);
long long value=key[size];
if(lchild(j)==size)j=lchild(j);
else if(rchild(j)<=size)
j=(key[lchild(j)]>key[rchild(j)])?lchild(j):rchild(j);
if(value>=key[j])
fool_max_insert(value,cur);
else
{
fool_max_insert(key[j],cur);
fool_min_insert(value,j);
}
size--;
return e;
}
int main()
{
heap h;
h.init();
long long n,pts;
char ch;
scanf("%lld",&n);
while(n-->0)
{
getchar();
scanf("%c",&ch);
if(ch=='I')
{
scanf("%lld",&pts);
h.insert(pts);
}
else if(ch=='H')
printf("%lld\n",h.del_max());
else if(ch=='L')
printf("%lld\n",h.del_min());
}
return 0;
}  回復  更多評論
  
# re: 基于雙端堆實現的優先級隊列(2): 內幕[未登錄] 2014-01-05 16:02 | 春秋十二月
@Cppowboy
是不是操作后,序列違反了雙端堆的性質?我的代碼是可以用的,當時做過很久的隨機測試,都沒有違反性質。  回復  更多評論
  
# re: 基于雙端堆實現的優先級隊列(2): 內幕[未登錄] 2014-01-05 16:11 | 春秋十二月
@Cppowboy
實現細節可以不同,我的實現與stl中的優先級隊列類似,關鍵是各種操作后,保證序列不違反性質就行了。  回復  更多評論
  
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲人成艺术| 亚洲精品一区在线观看香蕉| 中文一区字幕| 蜜桃av一区二区| 亚洲成人在线免费| 国产欧美一区二区精品仙草咪| 亚洲国产高清一区二区三区| 正在播放亚洲一区| 国产精品一区二区三区久久久| 欧美一区二区视频免费观看| 久久精品国产精品| 亚洲啪啪91| 亚洲欧美另类久久久精品2019| 99这里有精品| 欧美99在线视频观看| 亚洲日本成人网| 久久免费视频这里只有精品| 欧美在线免费视频| 日韩午夜av在线| 99这里有精品| 久久精品最新地址| 亚洲国产精品第一区二区| 亚洲精品偷拍| 午夜久久久久| 蜜桃av综合| 国产精品日韩精品欧美在线| 激情久久中文字幕| 亚洲一区二区三区影院| 久久久亚洲国产天美传媒修理工| 亚洲福利视频网| 一本久道久久综合中文字幕 | 欧美超级免费视 在线| 亚洲激情网站| 亚洲欧美美女| 欧美激情一区二区三区在线| 国产亚洲欧美在线| 一区二区欧美亚洲| 免费成人激情视频| 亚洲一区二区三区四区视频| 欧美a级理论片| 好吊日精品视频| 亚洲欧美精品伊人久久| 亚洲国产综合91精品麻豆| 小嫩嫩精品导航| 国产精品magnet| 亚洲精品国产精品国产自| 久久亚洲视频| 亚洲一级在线| 欧美三区美女| 日韩一区二区精品在线观看| 欧美高清视频一区二区| 久久精品国产欧美亚洲人人爽| 国产精品系列在线| 亚洲综合精品| 亚洲视频成人| 国产精品毛片一区二区三区| 亚洲一区二区三区乱码aⅴ蜜桃女 亚洲一区二区三区乱码aⅴ | 久久久久久亚洲综合影院红桃| 99亚洲一区二区| 欧美理论电影网| 99国内精品久久| 亚洲激情在线观看视频免费| 噜噜噜91成人网| 91久久夜色精品国产九色| 久久综合国产精品| 久久综合九色九九| 免费在线欧美视频| 亚洲第一在线综合网站| 久久久欧美一区二区| 午夜精品av| 国产一区二区欧美| 久久久久青草大香线综合精品| 亚洲欧美日韩精品在线| 国产模特精品视频久久久久 | 一区二区av| 亚洲美女在线观看| 欧美视频在线观看免费网址| 亚洲永久免费视频| 欧美一级二区| 尤物精品国产第一福利三区| 亚洲东热激情| 欧美三级电影精品| 久久精品国产在热久久| 久久久久国产一区二区三区四区| 亚洲第一免费播放区| 亚洲精品色婷婷福利天堂| 欧美午夜精品伦理| 久久九九免费视频| 欧美成年人视频网站欧美| 亚洲天堂久久| 午夜精品一区二区三区在线播放| 在线观看国产日韩| 亚洲精品视频免费在线观看| 国产精品网红福利| 欧美a一区二区| 欧美日韩精品一区二区三区四区 | 亚洲成人在线网站| 欧美午夜精品久久久久久久| 久久婷婷国产综合国色天香| 欧美久久久久免费| 久久综合电影一区| 欧美视频网站| 男人天堂欧美日韩| 国产精品美女久久久久av超清| 久久精品国产久精国产爱| 美女视频一区免费观看| 亚洲专区一区| 欧美 日韩 国产精品免费观看| 欧美一区成人| 欧美日韩国产123区| 免费不卡在线观看| 国产啪精品视频| 日韩视频国产视频| 亚洲福利小视频| 亚洲欧美日韩精品| 中国av一区| 欧美大片在线看| 久久久久久久性| 国产精品久久久久一区二区三区| 欧美大尺度在线| 国精品一区二区三区| 中文欧美字幕免费| 99在线热播精品免费| 老牛嫩草一区二区三区日本| 在线欧美视频| 亚洲一区二区三| 欧美在线二区| 亚洲精品在线观看免费| 亚洲婷婷综合色高清在线 | 亚洲国产视频a| 亚洲专区在线视频| 99re6热在线精品视频播放速度| 午夜精品在线观看| 亚洲在线一区二区| 欧美大色视频| 亚洲成人在线视频网站| 激情久久五月| 久久精品国产精品亚洲综合 | 欧美激情第六页| 亚洲欧美另类在线| 久久综合成人精品亚洲另类欧美| 久久视频国产精品免费视频在线| 久久婷婷人人澡人人喊人人爽| 久久这里有精品15一区二区三区| 欧美日本在线视频| 国产精品免费视频观看| 亚洲精品国偷自产在线99热| 校园春色综合网| 欧美日韩在线一区| 亚洲看片一区| 久久亚洲综合| 一区二区三区欧美成人| 欧美人体xx| 欧美黄色免费网站| 午夜精品免费在线| 欧美日本一区二区三区| 国产精品久久网站| 亚洲精品一区二区三区在线观看 | 亚洲女优在线| 国产精品欧美日韩一区二区| 亚洲制服丝袜在线| 久久久久久一区二区三区| 狠狠综合久久av一区二区小说| 欧美专区日韩专区| 欧美国产激情| 一区二区三区高清| 国产欧美精品一区二区色综合| 欧美伊人久久| 欧美本精品男人aⅴ天堂| 亚洲欧美日韩综合aⅴ视频| 榴莲视频成人在线观看| 99精品免费| 国产精品家庭影院| 欧美伊人久久久久久久久影院| 美女主播精品视频一二三四| 亚洲伦理在线观看| 国产色爱av资源综合区| 蜜臀久久99精品久久久久久9| 日韩一区二区免费看| 久久精品卡一| 9l视频自拍蝌蚪9l视频成人| 国产农村妇女精品一二区| 久热精品在线视频| 亚洲小说春色综合另类电影| 久久中文久久字幕| 亚洲午夜国产一区99re久久| 黑人巨大精品欧美一区二区| 欧美日韩国产在线一区| 久久国产精品99精品国产| 日韩视频中文| 欧美成人69av| 久久久国产精品一区| 亚洲视频精选在线| 亚洲国产婷婷香蕉久久久久久| 国产欧美日韩另类视频免费观看| 欧美理论在线| 麻豆精品传媒视频| 久久九九免费视频| 午夜亚洲精品| 亚洲一区二区三区四区五区黄 |