/*binary_heap.c -- 二元堆積實現檔案*/<br />#include <stdio.h><br />#include <stdlib.h><br />#include "binary_heap.h"</p><p>/*局部函式宣告*/</p><p>/*返回 item 在 position 位置處上濾後應該出現堆中的位置索引*/<br />static int Percolate_Up (const Heap * const pheap, const Item item, const int position) ;<br />/*返回 item 在 position 位置處下濾後應該出現堆中的位置索引*/<br />static int Percolate_Down (const Heap * const pheap, const Item item, const int position) ;</p><p>/*介面函數定義*/</p><p>int InitializeHeap (Heap * const pheap, const int capacity)<br />{<br />*pheap = (struct heap *) malloc (sizeof (struct heap)) ;<br />if (NULL == *pheap)<br />{<br />puts ("Out of space.[1]") ;<br />return 0 ;<br />}<br />(*pheap) -> array = (Item *) malloc (sizeof (Item) * (capacity + 1)) ;<br />if (NULL == (*pheap) -> array)<br />{<br />puts ("Out of space.[2]") ;<br />free (*pheap) ;<br />return 0 ;<br />}<br />(*pheap) -> capacity = capacity ;<br />(*pheap) -> size = 0 ;<br />(*pheap) -> array[0] = MINDATA ;</p><p>return 1 ;<br />}</p><p>int HeapIsEmpty (const Heap * const pheap)<br />{<br />return 0 == (*pheap) -> size ;<br />}</p><p>int HeapIsFull (const Heap * const pheap)<br />{<br />return (*pheap) -> capacity == (*pheap) -> size ;<br />}</p><p>int Insert (const Heap * const pheap, const Item item)<br />{<br />int i ;</p><p>if (HeapIsFull (pheap))<br />return 0 ;<br />(*pheap) -> size++ ;<br />i = Percolate_Up (pheap, item, (*pheap) -> size) ;<br />(*pheap) -> array[i] = item ;</p><p>return 1 ;<br />}</p><p>Item DeleteMin (const Heap * const pheap)<br />{<br />Item min_item, item ;<br />int position = 1, i;</p><p>if (HeapIsEmpty (pheap))<br />{<br />puts ("Priority queue is empty.") ;<br />return (*pheap) -> array[0] ;<br />}<br />min_item = (*pheap) -> array[1] ;<br />item = (*pheap) -> array[(*pheap) -> size] ;<br />(*pheap) -> size-- ;<br />i = Percolate_Down (pheap, item, position) ;<br />(*pheap) -> array[i] = item ;</p><p>return min_item ;<br />}</p><p>int DecreaseKey (const Heap * const pheap, const int position, const Item triangle)<br />{<br />Item item ;<br />int i ;</p><p>if (HeapIsEmpty (pheap) || position > (*pheap) -> size || triangle < 0)<br />return 0 ;<br />item = (*pheap) -> array[position] -= triangle ;<br />i = Percolate_Up (pheap, item, position) ;<br />(*pheap) -> array[i] = item ;</p><p>return 1 ;<br />}</p><p>int IncreaseKey (const Heap * const pheap, const int position, const Item triangle)<br />{<br />Item item ;<br />int i ;</p><p>if (HeapIsEmpty (pheap) || position > (*pheap) -> size || triangle < 0)<br />return 0 ;<br />item = (*pheap) -> array[position] += triangle ;<br />i = Percolate_Down (pheap, item, position) ;<br />(*pheap) -> array[i] = item ;</p><p>return 1 ;<br />}</p><p>int Delete (const Heap * const pheap, const int position)<br />{<br />Item triangle ;</p><p>if (HeapIsEmpty (pheap) || position > (*pheap) -> size)<br />return 0 ;<br />//求出確保將 position 處的值放到二元堆積首的改變數 triangle<br />triangle = (*pheap) -> array[position] - (*pheap) -> array[1] + 1 ;<br />DecreaseKey (pheap, position, triangle) ;<br />DeleteMin (pheap) ;</p><p>return 1 ;<br />}</p><p>int BuildHeap (const Heap * const pheap, const Item * const array, const int array_size)<br />{<br />Item item ;<br />int ct, i ;</p><p>if (!HeapIsEmpty (pheap) || array_size > (*pheap) -> capacity)<br />return 0 ;<br />//以結構特性將數組中的元素放入二元堆積中<br />for (i = 1; i <= array_size; i++)<br />{<br />(*pheap) -> array[i] = array[i - 1] ;<br />(*pheap) -> size++ ;<br />}<br />for (ct = (*pheap) -> size / 2; ct > 0; ct--)<br />{<br />item = (*pheap) -> array[ct] ;<br />i = Percolate_Down (pheap, item, ct) ;<br />(*pheap) -> array[i] = item ;<br />}</p><p>return 1 ;<br />}</p><p>void Traversal (const Heap * const pheap, void (* pfun) (const Item item))<br />{<br />int ct, size ;</p><p>for (ct = 1, size = (*pheap) -> size; ct <= size; ct++)<br />(* pfun) ((*pheap) -> array[ct]) ;<br />}</p><p>void Release (const Heap * const pheap)<br />{<br />free ((*pheap) -> array) ;<br />free (*pheap) ;<br />}</p><p>/*局部函數定義*/</p><p>static int Percolate_Up (const Heap * const pheap, const Item item, const int position)<br />{<br />int i ;</p><p>for (i = position; (*pheap) -> array[i / 2] > item; i /= 2)<br />(*pheap) -> array[i] = (*pheap) -> array[i / 2] ;</p><p>return i ;<br />}</p><p>static int Percolate_Down (const Heap * const pheap, const Item item, const int position)<br />{<br />int i, child ;</p><p>for (i = position; i * 2 <= (*pheap) -> size; i = child)<br />{<br />child = i * 2;<br />//條件判斷的前半部分是判斷當前 child 位置上的結點是否有有兄弟 後半部分是比較與其右兄弟的大小關係.這個方法真不錯<br />if (child != (*pheap) -> size && (*pheap) -> array[child + 1] < (*pheap) -> array[child])<br />child++ ;<br />if (item > (*pheap) -> array[child])<br />(*pheap) -> array[i] = (*pheap) -> array[child] ;<br />else<br />break ;<br />}</p><p>return i ;<br />}