日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

归并排序算法 C++实现与时间复杂度(考过)恋上数据结构笔记

發布時間:2025/3/20 c/c++ 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 归并排序算法 C++实现与时间复杂度(考过)恋上数据结构笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

復習梗概

  • 畫圖,自己整個數組,看代碼寫步驟,這個對理解歸并排序還是很有必要的
  • 合并兩個有序數組的merge函數寫法
  • 時間復雜度的分析方法!!!
  • 其實我覺得去b站找個動態的步驟分解視頻也是不錯的復習方法,當然要自己先回想
  • 歸并排序特點

  • 穩定,快速
  • 遞歸調用,分治思想
  • 合并兩個有序數組的思想
  • 時間復雜度O(nlogn),這個時間復雜度的分析方法很重要一定要掌握
  • 歸并排序時間復雜度分析(某校知能情報考過)

    戀上數據結構筆記 歸并排序與時間復雜度
    這個圖可能會很有用

    圖片來自:戀上數據結構結構與算法第二季-李明杰老師


    歸并排序本體函數

    從輸出也能大致看出來歸并排序的歸并順序,每次merge都會打印一次數組

    圖片來自:戀上數據結構結構與算法第二季-李明杰老師

    void mergeSort(vector<int> &array, int begin, int end) {//有點類似樹的遞歸訪問,每次調用都把當前數組一分為二,直到不可再分就return,兩個都return后,merge成一個有序數組,再不斷往回merge成有序數組if (end - begin + 1 < 2){return;}int mid = (begin + end) / 2;mergeSort(array, begin, mid);mergeSort(array, mid+1, end);merge(array, begin, end);vectorPrint(array); } 輸入數組: 6 9 3 1 2 0 8 29 15 11 10 歸并排序基礎版 6 9 3 1 2 0 8 29 15 11 10 3 6 9 1 2 0 8 29 15 11 10 3 6 9 1 2 0 8 29 15 11 10 3 6 9 0 1 2 8 29 15 11 10 0 1 2 3 6 9 8 29 15 11 10 0 1 2 3 6 9 8 29 15 11 10 0 1 2 3 6 9 8 15 29 11 10 0 1 2 3 6 9 8 15 29 10 11 0 1 2 3 6 9 8 10 11 15 29 0 1 2 3 6 8 9 10 11 15 29 算法用時:(微秒) [AlgoTime: 20007 us] 輸入數組: 6 9 3 1 2 0 8 29 15 11 10 歸并排序歸并換個寫法 6 9 3 1 2 0 8 29 15 11 10 3 6 9 1 2 0 8 29 15 11 10 3 6 9 1 2 0 8 29 15 11 10 3 6 9 0 1 2 8 29 15 11 10 0 1 2 3 6 9 8 29 15 11 10 0 1 2 3 6 9 8 29 15 11 10 0 1 2 3 6 9 8 15 29 11 10 0 1 2 3 6 9 8 15 29 10 11 0 1 2 3 6 9 8 10 11 15 29 0 1 2 3 6 8 9 10 11 15 29 算法用時:(微秒) [AlgoTime: 22006 us]

    merge函數!!重要(兩個有序數組合并成一個有序數組)


    圖片來自:戀上數據結構結構與算法第二季-李明杰老師

  • 這個函數比較重要
  • 重點理解三個指針的操作和循環終止的條件
  • 這個寫法不便于理解,后面那個比較好理解
  • //merge函數就是將兩個有序數組合并成一個有序數組,由于歸并排序中,這兩個數組都在一個數組內,所以這里參數begin是左數組的第一位,end是右數組的最后一位 //這里的begin,mid,end都代表的是數組下標 //merge的整體思想是,兩個有序數組,兩個指針分別指向首位,指針指向的二者進行比較,小的先放入新數組,同時插入的元素對應數組指針++,另一個不變,接著比 //還是畫圖比較好理解,但這個也不難 void merge(vector<int> &array, int begin, int end) {vector<int> temp = {};//定義臨時數組,用于暫時存放合并并排序的有序數組,最后再覆蓋給arrayint mid = (begin + end) / 2;//求mid,mid是左數組的終端,mid+1是右數組的起點,這和mergeSort函數中上面兩個遞歸調用的begin與mid和end是一樣的int tempPointer = 0;int leftBeginPointer = begin;//不要想當然以為左數組起點下標一定是0,這要看你傳進來的是從哪開始的數組int rightBeginPointer = mid + 1;//這里定義了三個指針,分別指向臨時數組的下一個插入位置(vector就不需要了,就是個擺設),左數組的下一個插入元素,右數組的下一個插入元素while (tempPointer != end + 1)//當臨時數組長度已經等于右數組末尾長度(左右數組長度和),說明都插入了,結束循環{if (array[leftBeginPointer] <= array[rightBeginPointer]){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}else if (array[rightBeginPointer] < array[leftBeginPointer]){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}//若檢測一個數組已經全部插入,則直接把另一個數組剩余元素全部插入退出即可if (leftBeginPointer == mid + 1){while (rightBeginPointer != end + 1){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}break;}else if (rightBeginPointer == end + 1){while (leftBeginPointer != mid + 1){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}break;}}//用臨時數組覆蓋array對應位置的數組for (int i = 0; i < end - begin + 1; i++){array[begin + i] = temp[i];} }

    merge函數寫法2

    這是merge函數的另一種寫法,因為寫法不是唯一的,多看看以免以后考到不會
    這個是先有一個數組全部插入了就截止,然后再把另一個數組剩余的全部插入

    void merge2nd(vector<int> &array, int begin, int end) {vector<int> temp = {};//定義臨時數組,用于暫時存放合并并排序的有序數組,最后再覆蓋給arrayint mid = (begin + end) / 2;//求mid,mid是左數組的終端,mid+1是右數組的起點,這和mergeSort函數中上面兩個遞歸調用的begin與mid和end是一樣的int tempPointer = 0;int leftBeginPointer = begin;//不要想當然以為左數組起點下標一定是0,這要看你傳進來的是從哪開始的數組int rightBeginPointer = mid + 1;//這里定義了三個指針,分別指向臨時數組的下一個插入位置,左數組的下一個插入元素,右數組的下一個插入元素while(leftBeginPointer<mid+1&&rightBeginPointer<end+1){if (array[leftBeginPointer] <= array[rightBeginPointer]){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}else if (array[rightBeginPointer] < array[leftBeginPointer]){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}}while(leftBeginPointer<mid+1){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}while(rightBeginPointer<end+1){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}//用臨時數組覆蓋array對應位置的數組for (int i = 0; i < end - begin + 1; i++){array[begin + i] = temp[i];} }

    完整代碼

    #include <iostream> #include <vector> #include "MeasureAlgoTime.hpp" using namespace std;// void vectorPrint(vector<int> &array) {for (int i = 0; i < array.size(); i++){cout << array[i] << ' ';}cout << endl; }//merge函數就是將兩個有序數組合并成一個有序數組,由于歸并排序中,這兩個數組都在一個數組內,所以這里參數begin是左數組的第一位,end是右數組的最后一位 //這里的begin,mid,end都代表的是數組下標 //merge的整體思想是,兩個有序數組,兩個指針分別指向首位,指針指向的二者進行比較,小的先放入新數組,同時插入的元素對應數組指針++,另一個不變,接著比 //還是畫圖比較好理解,但這個也不難 void merge(vector<int> &array, int begin, int end) {vector<int> temp = {};//定義臨時數組,用于暫時存放合并并排序的有序數組,最后再覆蓋給arrayint mid = (begin + end) / 2;//求mid,mid是左數組的終端,mid+1是右數組的起點,這和mergeSort函數中上面兩個遞歸調用的begin與mid和end是一樣的int tempPointer = 0;int leftBeginPointer = begin;//不要想當然以為左數組起點下標一定是0,這要看你傳進來的是從哪開始的數組int rightBeginPointer = mid + 1;//這里定義了三個指針,分別指向臨時數組的下一個插入位置(vector就不需要了,就是個擺設),左數組的下一個插入元素,右數組的下一個插入元素while (tempPointer != end + 1)//當臨時數組長度已經等于右數組末尾長度(左右數組長度和),說明都插入了,結束循環{if (array[leftBeginPointer] <= array[rightBeginPointer]){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}else if (array[rightBeginPointer] < array[leftBeginPointer]){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}//若檢測一個數組已經全部插入,則直接把另一個數組剩余元素全部插入退出即可if (leftBeginPointer == mid + 1){while (rightBeginPointer != end + 1){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}break;}else if (rightBeginPointer == end + 1){while (leftBeginPointer != mid + 1){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}break;}}//用臨時數組覆蓋array對應位置的數組for (int i = 0; i < end - begin + 1; i++){array[begin + i] = temp[i];} }void merge2nd(vector<int> &array, int begin, int end) {vector<int> temp = {};//定義臨時數組,用于暫時存放合并并排序的有序數組,最后再覆蓋給arrayint mid = (begin + end) / 2;//求mid,mid是左數組的終端,mid+1是右數組的起點,這和mergeSort函數中上面兩個遞歸調用的begin與mid和end是一樣的int tempPointer = 0;int leftBeginPointer = begin;//不要想當然以為左數組起點下標一定是0,這要看你傳進來的是從哪開始的數組int rightBeginPointer = mid + 1;//這里定義了三個指針,分別指向臨時數組的下一個插入位置,左數組的下一個插入元素,右數組的下一個插入元素while(leftBeginPointer<mid+1&&rightBeginPointer<end+1){if (array[leftBeginPointer] <= array[rightBeginPointer]){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}else if (array[rightBeginPointer] < array[leftBeginPointer]){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}}while(leftBeginPointer<mid+1){temp.push_back(array[leftBeginPointer]);tempPointer++;leftBeginPointer++;}while(rightBeginPointer<end+1){temp.push_back(array[rightBeginPointer]);tempPointer++;rightBeginPointer++;}//用臨時數組覆蓋array對應位置的數組for (int i = 0; i < end - begin + 1; i++){array[begin + i] = temp[i];} }void mergeSort(vector<int> &array, int begin, int end) {//有點類似樹的遞歸訪問,每次調用都把當前數組一分為二,直到不可再分就return,然后merge成一個有序數組,再不斷mergeif (end - begin + 1 < 2){return;}int mid = (begin + end) / 2;mergeSort(array, begin, mid);mergeSort(array, mid+1, end);merge(array, begin, end);vectorPrint(array); }void mergeSort2nd(vector<int> &array, int begin, int end) {if (end - begin + 1 < 2){return;}int mid = (begin + end) / 2;mergeSort2nd(array, begin, mid);mergeSort2nd(array, mid+1, end);merge2nd(array, begin, end);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;vectorPrint(array);time1.start();cout << "歸并排序基礎版" << endl;mergeSort(array, 0, array.size() - 1);cout << "算法用時:(微秒)";time1.printElapsed();cout << "輸入數組:" << endl;vectorPrint(array2);time1.start();cout << "歸并排序歸并換個寫法" << endl;mergeSort(array2, 0, array2.size() - 1);cout << "算法用時:(微秒)";time1.printElapsed();return 0; } 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

    總結

    以上是生活随笔為你收集整理的归并排序算法 C++实现与时间复杂度(考过)恋上数据结构笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。