堆的構建、堆的插入、堆的刪除、堆排序
阿新 • • 發佈:2019-01-30
#include<stdio.h> #include<stdlib.h> #define INIT_ARRAY_SIZE 50 int heap_size; //堆大小 int heap_cap_size; //堆容量大小 /*函式宣告*/ //構建堆 void build_heap(int array[], int length); //堆的調整 void max_heap_adjust(int array[], int index); //堆的刪除 void heap_delete(int array[], int value); //堆的插入 void heap_insert(int** array, int value); //堆排序 void heap_sort(int array[], int length); /*返回以index為根的完全二叉樹的左子樹的索引,整個二叉樹索引以0為開始*/ int left(int index) { return ((index << 1) + 1); } /*返回以index為根的完全二叉樹的右子樹的索引,整個二叉樹索引以0為開始*/ int right(int index) { return ((index << 1) + 2); } /*兩個數的交換*/ void swap(int* a ,int* b) { int temp = *a; *a = *b; *b = temp; return; } void build_heap(int array[], int length) { heap_size = length; for (int i = ((heap_size - 1) >> 1); i >= 0; --i) { max_heap_adjust(array, i); } } void max_heap_adjust(int array[], int index) { int left_index = left(index); int right_index = right(index); int largest = index; //左子樹和父節點進行對比 if (left_index <= (heap_size-1) && array[left_index] > array[largest]) { largest = left_index; } //右子樹和父節點進行對比 if (right_index <= (heap_size-1) && array[right_index] > array[largest] ) { largest = right_index; } if (largest == index) { return; } else { //需要交換 swap(&array[index], &array[largest]); //遞迴呼叫 max_heap_adjust(array, largest); } } void heap_delete(int array[], int value) { int index = 0; for (index = 0; index < heap_size; index++) { if (array[index] == value) { break; } } array[index] = array[heap_size - 1]; --heap_size; max_heap_adjust(array, index); } void heap_insert(int** array, int value) { int index = 0; int parent_index = 0; if (heap_size+1 > heap_cap_size) { *array = (int*) realloc(*array, 2*INIT_ARRAY_SIZE*sizeof(int)); } (*array)[heap_size] = value; //一定要記得加上()既(*array)[heap_size] 如果寫出*array[heap_size]肯定會出問題 index = heap_size; heap_size++;//要記得這裡堆大小變大了 //和父節點對比,哪個大就往上移動 while (index) { parent_index = ((index-1) >> 1); if ((*array)[parent_index] < (*array)[index]) { swap(&((*array)[parent_index]), &((*array)[index])); } index = parent_index; } } void heap_sort(int array[], int length) { int old_heap_size = heap_size; int i; for (i = length-1; i >= 1; --i) { swap(&array[i], &array[0]); --heap_size; max_heap_adjust(array, 0); } //恢復堆的大小 heap_size = old_heap_size; } void print_array(int* a , int length) { for (int i =0; i < length; i++) { printf("%d\t", a[i]); } printf("\n"); } int main() { int i = 0; int a[] = {9, 3, 7, 6, 5, 1, 10, 2}; int *array = NULL; array = (int *)malloc(INIT_ARRAY_SIZE*sizeof(int)); int length = sizeof(a)/sizeof(int); printf("陣列的長度是:%d\n", length); for (i = 0; i < length; ++i) { array[i] = a[i]; } printf("原始陣列為\n"); print_array(array, length); printf("堆的建立後的陣列\n"); build_heap(array, length); print_array(array, length); printf("堆排序後的陣列為\n"); heap_sort(array, length); print_array(array, length); //這個地方一定要記得先構建堆,不然下面執行刪除和插入有問題 build_heap(array, length); printf("刪除資料10後的陣列\n"); heap_delete(array, 10); length--; print_array(array, length); printf("插入資料10後的陣列\n"); length++; heap_insert(&array, 10); print_array(array, length); printf("堆排序後的陣列為\n"); heap_sort(array, length); print_array(array, length); return 0; }