ReviewForJob——堆排序
生活随笔
收集整理的這篇文章主要介紹了
ReviewForJob——堆排序
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
【0】README
1)本文旨在給出 推排序的源碼實(shí)現(xiàn);堆排序是基于二叉樹(shù)的數(shù)組實(shí)現(xiàn)的;
【1】堆排序步驟 step1)對(duì)排序數(shù)據(jù)建堆,執(zhí)行 n 次 insert 操作(基于上濾操作);每次 insert 包括 將 新元素插入到堆末尾,然后執(zhí)行 上濾操作; step2)執(zhí)行 n 次 deleteMin 操作(基于下濾操作),每一次 deleteMin 操作都包含 將 堆的根元素 和 堆最后一個(gè)元素交換,并對(duì)根 執(zhí)行 下濾操作; step3)經(jīng)過(guò) deleteMin 操作后, 堆所在的數(shù)組中的元素是 逆序的; Conclusion)由此可見(jiàn),堆排序的關(guān)鍵操作是 上濾操作 和 下濾操作;
【2】源碼實(shí)現(xiàn)(for full source code, please visit ?https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter7/review/p170_heap_sort?)
1)insert插入操作(基于上濾操作) // 插入操作 based on 上濾操作. void insert(BinaryHeap heap, ElementType data) {if(heap->size == heap->capacity-1){Error("failed insert() for heap is full.");} percolateUp(heap, data); }// 上濾操作(key operation) void percolateUp(BinaryHeap heap, ElementType data) {int i;// 必須將size++.for(i=++heap->size; data < heap->array[i/2]; i/=2){heap->array[i] = heap->array[i/2];}heap->array[i] = data; }2)deleteMin操作(基于下濾操作) // delete minimal from heap based on percolateDown(). void deleteMin(BinaryHeap heap) { if(heap->size==0){Error("failed deleteMin() for the heap is empty");return ;} swap(&heap->array[1], &heap->array[heap->size--]); // 將二叉堆的根和二叉堆的最后一個(gè)元素交換,size--。percolateDown(heap, 1); // 執(zhí)行下濾操作. }// 下濾操作(key operation) void percolateDown(BinaryHeap heap, int i) {int child;int temp; for(temp=heap->array[i]; (child=leftChild(i))<=heap->size; i=child){ if(child<heap->size && heap->array[child] > heap->array[child+1]){child++;}if(temp > heap->array[child]) // 比較是和 temp=heap->array[index] 進(jìn)行比較.{ heap->array[i] = heap->array[child];}else{ break;}}heap->array[i] = temp; }int leftChild(int index) {return 2*index; }// swap a and b. void swap(ElementType* a, ElementType* b) {ElementType t;t = *a;*a = *b;*b = t; } 對(duì)以上代碼的分析(Analysis):(最難實(shí)現(xiàn)的就是 下濾操作) A1)第21行 的?child<heap->size 是必須需要的,不要認(rèn)為 它 和 第19行的?(child=leftChild(i))<=heap->size 雷同了,因?yàn)橛锌赡?該節(jié)點(diǎn)只有左孩子,而沒(méi)有右孩子; A2)如下圖所示,size=4的堆:節(jié)點(diǎn)53就只有左孩子而沒(méi)有右孩子,所以第21行是不需要執(zhí)行的,這通過(guò) child<heap->size 來(lái)控制;
3)打印結(jié)果
【1】堆排序步驟 step1)對(duì)排序數(shù)據(jù)建堆,執(zhí)行 n 次 insert 操作(基于上濾操作);每次 insert 包括 將 新元素插入到堆末尾,然后執(zhí)行 上濾操作; step2)執(zhí)行 n 次 deleteMin 操作(基于下濾操作),每一次 deleteMin 操作都包含 將 堆的根元素 和 堆最后一個(gè)元素交換,并對(duì)根 執(zhí)行 下濾操作; step3)經(jīng)過(guò) deleteMin 操作后, 堆所在的數(shù)組中的元素是 逆序的; Conclusion)由此可見(jiàn),堆排序的關(guān)鍵操作是 上濾操作 和 下濾操作;
【2】源碼實(shí)現(xiàn)(for full source code, please visit ?https://github.com/pacosonTang/dataStructure-algorithmAnalysis/tree/master/chapter7/review/p170_heap_sort?)
1)insert插入操作(基于上濾操作) // 插入操作 based on 上濾操作. void insert(BinaryHeap heap, ElementType data) {if(heap->size == heap->capacity-1){Error("failed insert() for heap is full.");} percolateUp(heap, data); }// 上濾操作(key operation) void percolateUp(BinaryHeap heap, ElementType data) {int i;// 必須將size++.for(i=++heap->size; data < heap->array[i/2]; i/=2){heap->array[i] = heap->array[i/2];}heap->array[i] = data; }2)deleteMin操作(基于下濾操作) // delete minimal from heap based on percolateDown(). void deleteMin(BinaryHeap heap) { if(heap->size==0){Error("failed deleteMin() for the heap is empty");return ;} swap(&heap->array[1], &heap->array[heap->size--]); // 將二叉堆的根和二叉堆的最后一個(gè)元素交換,size--。percolateDown(heap, 1); // 執(zhí)行下濾操作. }// 下濾操作(key operation) void percolateDown(BinaryHeap heap, int i) {int child;int temp; for(temp=heap->array[i]; (child=leftChild(i))<=heap->size; i=child){ if(child<heap->size && heap->array[child] > heap->array[child+1]){child++;}if(temp > heap->array[child]) // 比較是和 temp=heap->array[index] 進(jìn)行比較.{ heap->array[i] = heap->array[child];}else{ break;}}heap->array[i] = temp; }int leftChild(int index) {return 2*index; }// swap a and b. void swap(ElementType* a, ElementType* b) {ElementType t;t = *a;*a = *b;*b = t; } 對(duì)以上代碼的分析(Analysis):(最難實(shí)現(xiàn)的就是 下濾操作) A1)第21行 的?child<heap->size 是必須需要的,不要認(rèn)為 它 和 第19行的?(child=leftChild(i))<=heap->size 雷同了,因?yàn)橛锌赡?該節(jié)點(diǎn)只有左孩子,而沒(méi)有右孩子; A2)如下圖所示,size=4的堆:節(jié)點(diǎn)53就只有左孩子而沒(méi)有右孩子,所以第21行是不需要執(zhí)行的,這通過(guò) child<heap->size 來(lái)控制;
3)打印結(jié)果
總結(jié)
以上是生活随笔為你收集整理的ReviewForJob——堆排序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ReviewForJob——希尔排序(缩
- 下一篇: ReviewForJob——快速排序(基