堆排序 C++代码实现及思想 排序过程输出 恋上数据结构笔记
生活随笔
收集整理的這篇文章主要介紹了
堆排序 C++代码实现及思想 排序过程输出 恋上数据结构笔记
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
復習梗概
文章目錄
- 復習梗概
- 什么是堆思想?
- 堆排序算法怎么來的?
- 什么是下濾?代碼
- 什么是建堆?代碼
- 堆排序本體 代碼及排序過程輸出 和時間復雜度
- 完整代碼
什么是堆思想?
堆排序算法怎么來的?
選擇排序算法優化來的
相比冒泡排序,選擇排序無法在內循環過程中,通過比較確定前面是否已經形成有序序列,因此我認為這里難以優化
但實際上可以從另一個地方優化:即選取未排序序列最大值這個過程,如果用堆完成的話,時間復雜度只有O(logn)(主要是下濾,結點的高度logn),整體復雜度O(nlogn)
因此,優化后的選擇排序算法 即為 堆排序
什么是下濾?代碼
什么是建堆?代碼
堆排序本體 代碼及排序過程輸出 和時間復雜度
完整代碼
#include <iostream> #include <vector> #include "MeasureAlgoTime.hpp" using namespace std;//! 選擇排序:從未排序序列中,找出最大的那個元素,與未排序序列的末尾元素交換, //! 不斷執行上述步驟(n-1輪),末尾最大元素形成有序序列(挑最小的也可以,看需求是升序還是降序) //! 最好最壞平均時間復雜度:O(n2) 空間復雜度:O(1) 屬于穩定排序 //! 相比冒泡排序,選擇排序無法在內循環過程中,通過比較確定前面是否已經形成有序序列,因此我認為這里難以優化 //! 但實際上可以從另一個地方優化:即選取未排序序列最大值這個過程,如果用堆完成的話,時間復雜度只有O(logn)(主要是下濾),整體復雜度O(nlogn) //! 因此,優化后的選擇排序算法 即為 堆排序void vectorPrint(vector<int> &array) {for (int i = 0; i < array.size(); i++){cout << array[i] << ' ';}cout << endl; }//堆的下濾函數 void siftDown(vector<int> &array, int index, int end) {//! 這里指對array的index元素進行下濾操作,這里的end指的是未排序的序列的末尾元素的index,因為vector容器的size是私有的不能改int biggerChildIndex = index * 2 + 1;while (biggerChildIndex <= end){if (biggerChildIndex + 1 <= end && array[biggerChildIndex] < array[biggerChildIndex + 1]){ // if確保若該結點存在右子結點,且右結點值大于左結點,則biggerChildIndex更新為右結點的index//若沒有右子結點,該語句不會觸發,且biggerChildIndex默認就是左子結點,妙啊biggerChildIndex++;}if (array[index] < array[biggerChildIndex]){int temp = array[index];array[index] = array[biggerChildIndex]; //發現子結點大于該結點,進行調換array[biggerChildIndex] = temp;index = biggerChildIndex;biggerChildIndex = index * 2 + 1; //若發生下濾,則更新index和childIndex,進行下一次下濾比較}else{break; //若子結點大于該結點,停止本次下濾}} }//利用已有的數組建立一個堆,實際上就是對數組里的元素進行排序(從下至上的下濾),使之符合堆的定義(每一個結點大于左右子結點) void BuildHeap(vector<int> &array) {int index = array.size() / 2 - 1; //這里是找到二叉堆的最后一個非葉子結點的位置,葉子結點不用下濾for (int i = index; i >= 0; i--){siftDown(array, i, array.size()); //從最后一個非葉子結點開始向上下濾(是建堆的兩種方法之一)} }void HeapSort(vector<int> &array) {BuildHeap(array);//! 對數組進行建堆后,array【0】就是該數組的最大值for (int end = array.size() - 1; end > 0; end--){vectorPrint(array);siftDown(array, 0, end);int temp = array[0];array[0] = array[end];array[end] = temp;//! 此時array【0】是原本隊尾的小元素,對其進行下濾,使這個堆的array【0】依舊是最大}vectorPrint(array); }int main() {Tools::Time::AlgoTimeUs time1;Tools::Time::AlgoTimeUs time2;Tools::Time::AlgoTimeUs time3;vector<int> array;array = {6, 9, 3, 1, 2, 0, 8, 29, 15, 11, 10};vector<int> array2 = array;vector<int> array3 = array;cout<<"輸入數組:"<<endl;time1.start();vectorPrint(array);cout << "堆排序基礎版" << endl;HeapSort(array);cout << "算法用時:(微秒)";time1.printElapsed();cout<<"排序完成:"<<endl;vectorPrint(array);return 0; }總結
以上是生活随笔為你收集整理的堆排序 C++代码实现及思想 排序过程输出 恋上数据结构笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 选择排序 C++代码实现及性能分析 恋上
- 下一篇: 插入排序算法 及其二分搜索优化版 C++