學習堆要有兩個前提 1:你學過二叉樹,不需要很精通,但是基本的結構你要知道 2:你學過線型表,隨便一種(鍊錶 順序表)都可以,為了理解容量這個概念。
堆實際上是在滿二叉樹基礎上做的乙個延拓,我們來看看滿二叉樹
如果你第一次接觸堆我們就來看個圖
線型表轉換成樹無非就是將這個線型表的元素依次放入這個完全二叉樹中,相反樹轉換成線性表就是將這個二叉樹的節點層次放入這個表中
首先我們將這個堆的節點構造出來
typedef
struct heap
heap;
老規矩還是先寫出最簡單的函式,判斷堆滿還是空。
bool heapempty
(heap *php)
bool heapfull
(heap *php)
然後就是我們堆的初始化銷毀
void
heapinit
(heap *php,
int sz)
void
heapdestroy
(heap *php)
接下來就是我們堆的核心,前面所講都是為了接下來的操作
我們補充幾個知識點:
乙個滿二叉樹
父節點(序號數)\* 2 = 左子節點;
父節點(序號數)\* 2 +1= 右子節點;
在堆中,涉及乙個調整,向上調整和向下調整,也就是我們常說的最小堆和最大堆
最大堆:根結點的鍵值是所有堆結點鍵值中最大者;
最小堆:根結點的鍵值是所有堆結點鍵值中最小者。
我們設計向下調整和向上調整這兩個函式就是為了實現這個最小堆和最大堆,也就是我們所謂的堆排。
在上**前我們規定所有的下標都是從 0 開始 ,我們需要傳入乙個調整的點作為初始調整點
void
_adjustup
(heap *php,
int start)
else
break;}
}
向上調整無非就是和父節點相比然後將小的放上去
來看向下調整
這時候我們需要注意的是我們先要找到堂兄關係節點中的最小的那個和
父節點相比較。
void
_adjustdown
(heap *php,
int start)
else
break;}
}
我們再做出來插入函式
bool heapinsert
(heap *php, datatype x)
然後再做出銷毀函式和展示函式
*
*void
heapdestroy
(heap *php)**
void
heapshow
(heap *php)
printf
("\n");
}
然後就是取堆頂元素
datatype heaptop
(heap *php)
return-1
;}
前面說這麼多呢是為了幹啥?堆排,對就是這個很多人哭著看完的演算法。
堆排的原理就將是通過堆的調整,找到最大(或最小的)數,之後把他和最後的數交換,並讓這個堆大小減一,那麼這個最大(或最小的數)就不再參與堆的調整了.我們為啥做這麼多函式呢?
就是為了實現這個堆排過程中的移動。當然還需要乙個函式就是將這個堆頂取出來然後將堆最後的元素補上去再向下調整。
bool heapremove
(heap *php)
我們先來看這個堆是怎麼構建出來的 :上**
int ar=
;int n =
sizeof
(ar)
/sizeof
(int);
heap hp;
int i;
heapinit
(&hp, n)
;for
(i =
0; i < n;
++i)
列印出來
我們畫圖看下
我們是不是期待這樣乙個二叉樹:
認為這就是我們那個堆,但是 show 出來就不一樣,因為我們堆這個堆在插入的時候做出了調整,也就是_adjustup,每插入乙個數都會向上調整。
來看過程
最後就調整成為了 這個情況,當然我們還需要看個步驟就是取一次堆頂會產生什麼現象
heapremove
(&hp)
;heapshow
(&hp)
;
繼續看圖
看到這堆排的所有能力就具備了,我們直接來看**
為了我們**能夠實現多個介面,我們多放幾個引數,乙個記錄起始位置,乙個記錄結束位置,對著一段數進行排序。
我們構建個小堆調整
void
_heapadjustdown
(int
*ar,
int left,
int right,
int start)
else
break;}
}void
heapsort
(int
* ar,
int left,
int right)
int end = right;
while
(end > left)
}
來看主函式怎麼呼叫
int ar=
;int n =
sizeof
(ar)
/sizeof
(int);
heapsort
(ar,
0, n-1)
;for
(int i =
0; i < n-1;
++i)
這就 o 了。。。。。
堆排的使用一般在資料量很大的時候其演算法複雜度是小於 2n|log 2 n|。看完這你是否掌握了呢?
資料結構 堆
最大堆 最小堆 堆的定義是 n個元素的序列,當且僅當滿足如下關係時被成為堆 1 ki k2i 且 ki k2i 1 或 2 ki k2i 且 ki k2i 1 i 1,2,n 2 當滿足 1 時,為最小堆,當滿足 2 時,為最大堆。若將此序列對應的一維陣列堪稱是乙個完全二叉樹,則2i和2i 1個節點...
資料結構 堆
資料結構 堆的操作和實現 當應用優先順序佇列或者進行堆排序時,一般利用堆來實現。堆是乙個完全 除最底層 外都是滿的 二叉樹,並滿足如下條件 1 根結點若有子樹,則子樹一定也是堆。2 根結點一定大於 或小於 子結點。因為要求堆必須是完全二叉樹,所以可以用線性的資料結構,比如陣列,來實現堆。利用陣列實現...
資料結構 堆
堆常用來實現優先佇列,在這種佇列中,待刪除的元素為優先順序最高 最低 的那個。在任何時候,任意優先元素都是可以插入到佇列中去的,是電腦科學中一類特殊的資料結構的統稱 最大 最小 堆是一棵每乙個節點的鍵值都不小於 大於 其孩子 如果存在 的鍵值的樹。大頂堆是一棵完全二叉樹,同時也是一棵最大樹。小頂堆是...