堆以及堆的相關應用

2021-07-08 12:46:44 字數 2637 閱讀 5935

本文中的堆是一種樹形資料結構,可以把堆看成一種特殊的完全二叉樹,再從二叉樹上加上一些限制條件即可以構成堆。即要求父節點元素全部都大於或等於子節點元素,或者小於等於。

這就構成了倆種堆:

堆的常見應用為:

使用堆進行排序,也就是常說的堆排序,時間複雜度為nlgn(這是比較排序時間複雜度的下限,即使用比較的排序方法,時間複雜度不可能比這個更低了)。其具體的做法是利用大根堆(假設此時堆的元素個數尾heapsize-1),每次把堆頂元素和堆尾元素表交換,那麼最大的元素就再堆尾了,這就算確定了乙個元素的最終位置,然後再把新的包含heapsize-1個元素的堆進行位置調整,因為之前的調換有可能破壞的堆。這個過程迭代到堆元素為0即結束,此時元素已經排序好了。

實現最大優先佇列,優先佇列是一種用來維護元素構成集合s的資料結構,乙個最大優先佇列支援一下操作

1.insert(s,x) 把x插入結合s

2.maxmum(s),返回s中關鍵字最大的元素

3.extractmax(s),返回並且刪除s中關鍵字最大的元素。

4.incresment-key(s,x,k),把元素x的關鍵字增加到k,這裡假設k不小於x的原關鍵字值。 最大優先佇列的應用很多,其中乙個就是共享計算機的作業排程,對打優先佇列記錄各個作業之間的優先順序,當乙個作業完成或者被中斷時,呼叫extreacmax從等待作業中選出優先順序最高的執行,在任何時候都可以呼叫insert來插入乙個作業。

實現最小優先佇列,主要用在事件排程的模擬器。

說完了堆的基本概念和應用,下面我們來看你看堆具體怎麼實現。

再次我們用陣列實現堆,首先再一棵二叉樹中加入根的位置是i(陣列從1開始,0號單元不用)那門其左子輸的位置就為2×i,右子樹的位置為2×i+1.其父節點的位置就為i/2.把這些關係寫成函式有:

int parent(int i)

int right(int i)

int left(int i)

我們把建堆的步驟分解:

max_heap維護堆的性質。

給定乙個節點a[i]找出其左右子節點和a[i]三個數的最大值,把a[i]和最大值調換,對於調換過的節點,遞迴實現此過程。

build_max_heap從後往前維護堆的性質,當這個過程完成以後,整個堆就建立了。

對所有非葉子節點實現max_heap過程即可建立乙個堆。 下面給出堆排序具體實現其中包含了建堆以及排序:

#include

int parent(int i)

int right(int i)

int left(int i)

int heapsize=10;

//維護堆的性質

void max_heap(int a,int i,int heapsize)

}//建堆,從len/2以後的位置節點均為子節點,而且必須從後往前建堆即從

//len/2--->1

void build_max_heap(int a,int len)

}//每次取最大的放在最後,剩下的調整位置成為乙個新的堆

void heap_sort(int a,int heapsize)

}int main();

build_max_heap(a,10);

heap_sort(a,heapsize);

int i=0;

for(i=1;i<=len;i++)

printf("%d ",a[i]);

printf("\n");

return

0;}

下面給出最大優先佇列實現**:

#include

#include

typedef struct heapheap;

int parent(int i)

int left(int i)

int right(int i)

//保持堆的性質

void max_heap(heap *a,int i)

if(r<=a->heapsize&&a->data[r]>a->data[largest])

if(i!=largest)

}void build_max_heap(heap* a)

}int heap_maxmun(heap *a)

int heap_extract_max(heap *a)

void heap_incresment_key(heap *a,int i,int key)

}void heap_max_heap_insert(heap *a,int key)

int main()

// a.data=;

a->heapsize=10;

build_max_heap(a);

for(i=1;i<=a->heapsize;i++)

printf("\n");

printf("%d",heap_extract_max(a));

printf("\n");

heap_max_heap_insert(a,10);

heap_incresment_key(a,3,11);

for(i=1;i<=a->heapsize;i++)

printf("%d ",a->data[i]);

printf("\n");

}

堆以及堆的實際應用

1.堆的概念 堆的儲存可以看成是陣列儲存的變形,不過,堆的儲存又具有二叉樹的結構,堆的儲存按型別可以分為大堆和小堆。小堆 大堆 中 任一節點的關鍵碼均小於 大於 等於它的左右孩子的關鍵碼,位於堆頂節點的關鍵碼最小 最大 從根節點到每個結點的路徑上陣列元素組成的序列都是遞增 遞減 的。2.堆的建立 堆...

堆相關問題

講堆不得不提的就是優先佇列。什麼是優先佇列?普通佇列 先進先出,後進後出 如何實現優先佇列?由上圖可知,用堆來實現優先佇列是乙個理想的方法。這裡採用二叉堆 最大堆 的定義 所有節點的值都不大於其父節點的值 二叉堆是乙個完全二叉樹 採用陣列來儲存二叉堆 由二叉堆的定義可以得出結論 對一顆完全二叉樹按層...

堆的相關演算法

堆是一種特殊的二叉樹。它具有下面兩個性質 1 每乙個節點的值大於或等於其每乙個子節點的值。2 該樹全然平衡,最後一層的葉子都處於最左側的位置。有最大堆和最小堆之分。以上定義是最大堆的定義,最小堆的定義例如以下 1 每乙個節點的值小於或等於其每乙個子節點的值 2 該樹全然平衡,最後一層的葉子都處於最左...