普通的二叉樹是不適合用陣列來儲存的,因為可能會存在大量的空間浪費。而完全二叉樹更適合使用順序結構儲存。現實中我們通常把堆(一種二叉樹)使用順序結構的陣列來儲存。需要注意的是這裡的堆和作業系統虛擬程序位址空間中的堆是兩回事,乙個是資料結構,乙個是作業系統中管理記憶體的一塊區域分段。
如果有乙個關鍵碼的集合k = ,把它的所有元素按完全二叉樹的順序儲存方式儲存在乙個一維陣列中,並滿足:ki <= k2i+1 且 ki<= k2i+2 (ki >= k2i+1 且 ki >= k2i+2) i = 0,1,2…,則稱為小堆(或大堆)。將根節點最大的堆叫做最大堆或大根堆,根節點最小的堆叫做最小堆或小根堆。介面的實現:堆中某個節點的值總是不大於或不小於其父節點的值;
堆總是一棵完全二叉樹;
每個子樹都是乙個堆;
建立堆:從倒數的第乙個非葉子節點的子樹開始調整,一直調整到根節點的樹,就可以調整成堆
向下調整adjustdown演算法:根據父節點總是大於或者小於子節點的值進行調整
向上調整adjustup演算法:根據左右子樹都是乙個堆進行調整
#pragma once
/*** 堆中某個節點的值總是不大於或不小於其父節點的值
** 堆總是乙個完全二叉樹
*/typedef int datatype;
typedef struct heap heap;
typedef int(*cmp_)(datatype, datatype); // 宣告函式指標
// 比較函式
int less(datatype x, datatype y);
int greater(datatype x, datatype y);
void swap(datatype* x, datatype* y);
void checkcapacity(heap* heap); // 擴容
void adjustdown(heap* heap, int size, int parent, cmp_ cmp);
void adjustup(heap* heap, int size, int parent, cmp_ cmp);
void createheap(heap* heap, datatype* arr, int size, cmp_ cmp);
void insert(heap* heap, datatype value); // 插入
int size(heap* heap); // 堆的節點個數
int empty(heap* heap); // 堆是否為空
datatype top(heap* heap); // 返回堆頂
void erase(heap* heap); // 刪除堆頂
void destroy(heap* heap);
#include "heap.h"
#include #include void swap(datatype* x, datatype* y)
void checkcapacity(heap* heap)
// 2.賦值
for (int i = heap->size - 1; i >= 0; --i)
// 3.釋放舊空間
free(heap->array);
heap->array = newarr;
heap->capacity = newcapacity; }}
void createheap(heap* heap, datatype* arr, int size, cmp_ cmp)
// 2.將二叉樹層序遍歷後得到的陣列,賦給動態申請的空間
for (int i = 0; i < size; ++i)
heap->capacity = size;
heap->size = size;
// 父節點與孩子節點下標的關係
// 父節點:n
// 左孩子節點:n*2+1 右孩子節點:n*2+2
// 孩子節點與父節點的關係: (孩子節點 - 1)/ 2 == 父親節點
int last = ((heap->size - 1 - 1) >> 1); // 獲取最後乙個非葉子節點的下標
// (小)堆的性質:堆頂元素小於所有的元素
while ( last >= 0 )
}void adjustdown(heap* heap, int size, int parent, cmp_ cmp)
if ( !cmp(heap->array[parent], heap->array[child]) )
else }}
void adjustup(heap* heap, int size, int child, cmp_ cmp)
}void insert(heap* heap, datatype value) // 插入
int size(heap* heap) // 堆的節點個數
int empty(heap* heap) // 堆是否為空
datatype top(heap* heap) // 返回堆頂
void erase(heap* heap) // 刪除堆頂
void destroy(heap* heap)
#include "heap.h"
#include #include int less(datatype x, datatype y)
return 0;
}int greater(datatype x, datatype y)
return 0;
}void print(heap* heap)
printf("\n");
}int main() ;
int len = sizeof(arr) / sizeof(arr[0]);
createheap(&heap, arr, len, less);
printf("top = %d\n", top(&heap));
printf("size = %d\n", size(&heap));
print(&heap);
insert(&heap, 5);
printf("top = %d\n", top(&heap));
printf("size = %d\n", size(&heap));
print(&heap);
erase(&heap);erase(&heap);
printf("top = %d\n", top(&heap));
printf("size = %d\n", size(&heap));
print(&heap);
destroy(&heap);
system("pause");
return 0;
}
#include "head.h"
// 堆排序(特殊的選擇排序)
// o(n^2) 不穩定
void adjust(int arr, int size, int parent)
if (arr[child] < arr[parent])
else }}
void heapsort(int arr, int size)
// 2.排序
int end = size - 1;
while (end >= 0)
}
二叉堆的實現
include include define max heap size 101 class binaryminheap void insert intvalue void removemin intgetmin void displayheaparray private int heaparray...
二叉堆的實現
1.堆的概念 這裡只需要注意兩點 a.堆的儲存方式 就是順序儲存在陣列中,在二叉樹中表現為滿二叉樹 b.堆的用處 用於排序,查詢最大最小都非常方便 2.堆的實現 heapexception.h ifndef heapexception h define heapexception h class a...
二叉堆的實現
二叉堆是一種特殊的堆,二叉堆是完全二元樹 二叉樹 或者是近似完全二元樹 二叉樹 二叉堆有兩種 最大堆和最小堆。最大堆 父結點的鍵值總是大於或等於任何乙個子結點的鍵值 最小堆 父結點的鍵值總是小於或等於任何乙個子節點的鍵值。二叉堆一般都通過 陣列 來實現。陣列實現的二叉堆,父節點和子節點的位置存在一定...