修煉演算法內功 歸併排序(一)

2021-08-23 14:21:51 字數 2812 閱讀 8252

內容:

歸併排序演算法思想

歸併排序演算法的實現

歸併排序演算法的優化

1、歸併排序演算法思想

對於給定的一串陣列如:5、3、7、2、6、4、8、1

我們可以進行如下幾個步驟:

將陣列從中間分成兩組陣列——>5、3、7、2和6、4、8、1分別排序;

同樣,我們可以繼續拆分這兩個陣列為5、3和7、2以及6、4和8、1分別排序;

我們將想要排序的陣列拆分再排序,就會形成迴圈,直到不能拆分為止。

排序完成後,再將排序完成後的陣列合併。

分治法:將乙個大的問題,分成若干個小的問題來處理,再將結果合併。

遞迴:在迴圈過程中,我們不斷拆分陣列本身,即不斷呼叫遞迴函式。

遞迴到底:陣列的長度是有限的,不斷拆分後,陣列就會拆分為只有乙個元素時,陣列就會無法拆分,遞迴結束。

演算法分析:

2-路歸併排序

兩路歸併:就是將兩個有序表合併成乙個有序表。即上述排序完成後,進行合併操作。

內容:對於陣列我們給定三個指標:陣列第乙個元素first,中間元素mid,最後乙個元素last。傳入陣列到函式是,我們就呼叫函式繼續將[first,mid]和[mid+1,last]傳入函式,即迴圈拆分陣列,直到遞迴到底。然後,對拆分後陣列進行排序合併。即:

template

void mergesort(t arr,int first,int last)

歸併操作:——void merge(int arr,int first,int mid,int last);

1)、對於兩個陣列合併,需要三個索引和乙個輔助空間temp。即int i=first;用於訪問第乙個陣列,int j=mid+1;用於訪問第二個陣列。k用來表示輔助空間temp的索引。

2)、同時,我們事先需要申明一塊記憶體大小為last-first+1空間用來儲存之前未拆分的陣列(就是傳入merge()函式的陣列)即——

int *temp = new int[last - first + 1];//申請一塊輔助空間用來儲存傳入函式的陣列arr中的資料

for (int i = first;i <= last;i++)

3)、從頭逐一比較兩個陣列([firsr,mid]和[mid+1,last])之間大小,較小者存入陣列arr中,i走完[firsr,mid],j走完[mid+1,last]就完成了合併操作。

int i = first, j = mid + 1;//建立索引:i表示陣列[first,mid]索引,j表示陣列[mid+1,last]陣列的索引

for (int k = first;k <=last;k++)//k指向陣列中第乙個元素

else if (j > last)//考慮到j越界

else if (temp[i - first] < temp[j - first])//注意:j是隨著i相對變化的,偏移量也是first

else 

}

或者這麼寫:

//將有二個有序數列a[first...mid]和a[mid...last]合併。

void mergearray(int a, int first, int mid, int last, int temp)

while (i <= m)

temp[k++] = a[i++];

while (j <= n)

temp[k++] = a[j++];

for (i = 0; i < k; i++)

a[first + i] = temp[i];

}

2、歸併排序演算法的實現

#includeusing namespace std;

//歸併排序

templatevoid mergesort(t arr,int n)

templatevoid mergesort(t arr,int first,int last)

templatevoid merge(t arr,int first,int mid,int last)

int i = first, j = mid + 1;//建立索引:i表示陣列[first,mid]索引,j表示陣列[mid+1,last]陣列的索引

for (int k = first;k <=last;k++)//k指向陣列中第乙個元素

else if (j > last)//考慮到j越界

else if (temp[i - first] < temp[j - first])//注意:j是隨著i相對變化的,偏移量也是first

else

}}int main()

; int len = sizeof(a) / sizeof(a[0]);

cout << "排序前:";

for (int i = 0;i < len;i++)

cout << a[i] << " ";

cout << endl;

mergesort(a,8);

cout << "排序後:";

for (int i = 0;i < len;i++)

cout << a[i] << " ";

cout << endl;

system("pause");

return 0;

}

修煉內功 資料結構與演算法11 歸併排序

所謂歸併排序 指的是如果要排序乙個陣列 我們先把陣列從中間分成前後兩部分,然後對前後兩部分分別排序,再將排好序的兩部分合併在一起,這樣整個陣列就都有序了 歸併排序使用了分治思想 分治,顧名思義,就是分而治之,將乙個大問題分解成小的子問題來解決 歸併排序就是通過遞迴來實現的 這個遞迴的公式是每次都將傳...

修煉演算法內功 選擇排序(一)

內容 1 簡單的選擇排序 2 使用模板 泛型 使演算法更加靈活 3 使用結構體完成學生的name和score屬性的排序 4 隨機生成演算法測試用例。寫在前面 為什麼學習o n 2 的排序演算法?基礎 1 selection sort 選擇排序 基本思路 如 8 6 2 3 1 5 7 4 對乙個序列...

內功修煉之O n 的排序演算法(一)

本文參考程式設計師內功修煉課程,所有實現 均能在github上找到。一 選擇排序 selection sort 1 基本思想 給定陣列int arr 第 1趟排序,在待排序資料arr 1 arr n 中選出最小的 資料,將它與arr 1 交換 第 2趟,在待排序 資料arr 2 arr n 中選出最...