資料結構 堆(heap)

2021-08-21 14:17:51 字數 1809 閱讀 6558

堆(heap)也被稱為優先佇列(priority queue)。佇列中允許的操作是先進先出(fifo),在隊尾插入元素,在隊頭取出元素。而堆也是一樣,在堆底插入元素,在堆頂取出元素,但是堆中元素的排列不是按照到來的先後順序,而是按照一定的優先順序排列的。這個優先順序可以是元素的大小或者其他規則。如圖一所示就是乙個堆,堆優先順序就是大的元素排在前面,小的元素排在後面,這樣得到的堆稱為最大堆。最大堆中堆頂的元素是整個堆中最大的,並且每乙個分支也可以看成乙個最大堆。同樣的,我們可以定義最小堆,如圖二所示。

堆可以看成乙個二叉樹,所以可以考慮使用二叉樹的表示方法來表示堆。但是因為堆中元素按照一定的優先順序排列,因此可以使用更簡單的方法——陣列——來表示,這樣可以節省子節點指標空間,並且可以快速訪問每個節點。堆得陣列表示其實就是堆層級遍歷的結果,如下圖所示:

這樣對於每乙個下標為i的節點,其左子節點在下標為2*i的位置,其右子節點在下標為2*i+1的位置,而其父節點在下標為 floor,其中i從1開始。通過陣列的儲存方式,可以通過計算下標,直接獲取到相關節點。

typedef struct heap

heap;

#define min -1

heap* createemptyheap (int max)

heap->capacity = max;

heap->size = 0;

heap->arr = (int*)malloc(sizeof(int) * (heap->capacity + 1));

heap->arr[0] = min;

return heap;

}

最小堆為例,說明堆得插入、刪除等操作。

將新元素增加到堆的末尾

按照優先順序,將新元素與其父節點比較,如果新元素小於父節點則將兩者交換位置。

不斷進行第2步操作,直到不需要交換新元素和父節點,或者達到堆頂

最後通過得到乙個最小堆

通過將新元素與父節點調整交換的操作叫做上濾(percolate up)

heap* insert (heap* heap, int val) 

// percolate up new element

int i;

for (i = ++heap->size; heap->arr[i] > val; i /= 2)

heap->arr[i] = heap->arr[i/2];

heap->arr[i] = val;

return heap;

}bool isfull (heap* heap)

堆的刪除操作與插入操作相反,插入操作從下往上調整堆,而刪除操作則從上往下調整堆。

刪除堆頂元素(通常是將堆頂元素放置在陣列的末尾)

比較左右子節點,將小的元素上調。

不斷進行步驟2,直到不需要調整或者調整到堆底。

bool isempty (heap* heap) 

heap* deletemin (heap* heap)

int minelement = heap->arr[1];

int lastelement = heap->arr[heap->size--];

int i, childindex;

for (i = 1; 2*i <= heap->size; i = childindex)

heap->arr[i] = lastelement;

return heap;

}

資料結構 堆 heap

陣列表示 公式運算 堆就是用陣列實現的完全二叉樹,所以它沒有使用父指標或者子指標。堆根據 堆屬性 來排序,堆屬性 決定了樹中節點的位置。堆的根節點中存放的是最大或者最小元素,但是其他節點的排序順序是未知的。例如,在乙個最大堆中,最大的那乙個元素總是位於 index 0 的位置,但是最小的元素則未必是...

資料結構之堆Heap

1.概述 堆 也叫優先佇列 是一棵完全二叉樹,它的特點是父節點的值大於 小於 兩個子節點的值 分別稱為大頂堆和小頂堆 它常用於管理演算法執行過程中的資訊,應用場景包括堆排序,優先佇列等。2.堆的基本操作 堆是一棵完全二叉樹,高度為o lg n 其基本操作至多與樹的高度成正比。在介紹堆的基本操作之前,...

Heap 資料結構之堆

堆是一種資料結構,是一棵二叉樹 盡量地滿足完全二叉樹的規律 他有乙個特點,就是兩個兒子的值均大於或小於父節點。那麼這個堆就被稱為大頂堆或小頂堆。同一級的元素不比較大小,它可以用到優先佇列之中,還有其他很神奇的應用。其實就是乙個步驟 如果它不滿足堆的性質,那麼就繼續維護,否則結束。1.向上維護 如果節...