堆的基本操作

2021-08-19 23:07:34 字數 2680 閱讀 6611

堆的資料結構

對於堆, 有最大堆和最小堆, 在定義乙個堆的時候用乙個陣列表示堆, 同時為了方便定義堆的大小, 用乙個 size 表示堆的有效元素, 同時為了區別最大堆和最小堆, 我們用乙個函式指標表示這個堆是最大堆還是最小堆.

typedef

int (*compare)(heaptype parent, heaptype child);

typedef

struct heap heap;

堆的初始化
int greater(heaptype parent, heaptype child)

int less(heaptype parent, heaptype child)

void heapinit(heap* heap, compare cmp)

heap -> size = 0;

heap -> cmp = cmp;

}

堆的插入

先將要插入得到元素插入到堆對應的陣列的最後乙個位置, 然後判斷插入結點的值和它的父節點是否符合堆的特徵(最大堆:根節點大於它的左孩子和有孩子, 最小堆根節點小於它的左孩子和有孩子), 此時如果插入結點和它的父節點符合堆的特性就直接退出, 如果根節點和父節點不符合堆的特性, 此時就需要將插入結點和它的根節點進行交換, 直到符合堆的特性為止

void heapinsert(heap* heap, heaptype value)

if(heap -> size >= heapmaxsize)

//先將 value 插入到末尾

heap -> data[heap -> size++] = value;

//判斷父節點和 value 是否符合規定

int child = heap -> size - 1;

int parent = (child - 1) / 2;

while(child > 0)

//如果符合, 就退出

else

}}

取堆頂元素

直接返回堆對用的陣列的第乙個元素

int heaproot(heap* heap, heaptype* value)

*value = heap -> data[0];

return

1;}

刪除堆

先將堆的最後乙個元素和堆的第乙個結點進行交換, 將堆的大小減1, 此時由於交換了兩個元素, 因此可能會破壞堆的結構.先判斷父節點是否有右孩子, 如果有右孩子, 就將左右孩子中比較滿足多結構的乙個標記下來, 接著判斷父節點和左右孩子較滿足堆結構的的結點是否需要交換, 如果需要交換就將兩個交換, 否則就直接退出

void heaperase(heap* heap)

if(heap -> size == 0)

//將對頂元素和最後乙個元素進行交換

swap(&heap -> data[0], &heap -> data[heap -> size - 1]);

--heap -> size;

int parent = 0;

int child = 2 * parent + 1;

while(parent >= 0 && parent < heap -> size && child >= 0 && child < heap -> size)

//判斷是否需要下沉

if(heap -> cmp(heap -> data[parent], heap -> data[child]) == 0)

else

if(heap -> cmp(heap -> data[parent], heap -> data[child]) == 1)

}else

}}

堆的判空

判斷堆所對應的的陣列元素的個數是否為空, 如果為空就返回1, 否則就返回0

int heapempty(heap* heap)

if(heap -> size == 0)

return

0;}

判斷堆的元素的個數
int heapsize(heap* heap)

return heap -> size;

}

堆的銷毀
void heapdestroy(heap* heap)

heap -> size = 0;

heap -> cmp = null;

}

堆排序

給定乙個陣列, 將這個陣列按照對應的規則進行排序. 即先定義乙個堆, 再將陣列中的所有元素插入到堆中, 將堆中的元素刪除, 最後恢復對的有效元素, 將堆中的內容全部拷貝到陣列中

void heapsort(heaptype array, int size, compare cmp)

heap heap;

heapinit(&heap, cmp);

//先將陣列中的元素插入到堆中

int i = 0;

for(; i < size; i++)

//刪除對中的所有元素

for(i = 0; i < size; i++)

heap.size = size;

for(i = 0; i < size; i++)

}

堆的基本操作

堆的基本概念 如果有乙個關鍵碼的集合k 把它的所有元素按完全二叉樹的順序儲存方式儲存在乙個一維陣列中,並滿足 ki k2 i 1 且 ki k2 i 2 ki k2 i 1 且 ki k2 i 2 i 0,1,2 則稱為小堆 或大堆 如下圖 分別為小堆和大堆 堆的操作具體 如下 測試環境 vs201...

堆的基本操作

heap.h ifndef heap h define heap h 定義乙個函式指標 typedef int pf hdatatype left,hdatatype right typedef int hdatatype typedef struct heap heap int greater h...

堆的基本操作

堆 邏輯上是一顆完全二叉樹 物理上是陣列的形式 順序儲存 作用 找陣列中的前k大的值 特點 大頂堆 任意乙個root的值 左右子樹的值 小頂堆 任意乙個root的值 左右子樹的值 要調整root所在的節點 前提 root的左右子樹都已滿足堆的性質 如果root所在的節點已經是葉子結點,調整結束 找到...