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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > C# >内容正文

C#

归并排序算法(C#实现)

發布時間:2023/12/10 C# 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 归并排序算法(C#实现) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?歸并排序(Merge Sort)是利用"歸并"技術來進行排序。歸并是指將若干個已排序的子文件合并成一個有序的文件。歸并排序有兩種方式:1): 自底向上的方法 2):自頂向下的方法

?1、 自底向上的方法
(1) 自底向上的基本思想
???? 自底向上的基本思想是:第1趟歸并排序時,將待排序的文件R[1..n]看作是n個長度為1的有序子文件,將這些子文件兩兩歸并,若n為偶數,則得到n/2個長度為2的有序子文件;若n為奇數,則最后一個子文件輪空(不參與歸并)。故本趟歸并完成后,前n/2 - 1個有序子文件長度為2,但最后一個子文件長度仍為1;第2趟歸并則是將第1趟歸并所得到的n/2個有序的子文件兩兩歸并,如此反復,直到最后得到一個長度為n的有序文件為止。
???? 上述的每次歸并操作,均是將兩個有序的子文件合并成一個有序的子文件,故稱其為"二路歸并排序"。類似地有k(k>2)路歸并排序。???

?

2、自頂向下的方法(本文主要介紹此種方法,下面的文字都是對此種方法的解讀)

(1) 自頂向下的基本思想
???? 采用分治法進行自頂向下的算法設計,形式更為簡潔。
???? 自頂向下的歸并排序:是利用遞歸和分而治之的技術將數據序列劃分成為越來越小的半子表,再對半子表排序,最后再用遞歸步驟將排好序的半子表合并成為越來越大的有序序列,歸并排序包括兩個步驟,分別為:

????? 1)劃分子表

????? 2)合并半子表


(1)分治法的三個步驟
???? 設歸并排序的當前區間是R[low..high],分治法的三個步驟是:
①分解:將當前區間一分為二,即求分裂點
②求解:遞歸地對兩個子區間R[low..mid]和R[mid+1..high]進行歸并排序;
③組合:將已排序的兩個子區間R[low..mid]和R[mid+1..high]歸并為一個有序的區間R[low..high]。
? 遞歸的終結條件:子區間長度為1(一個記錄自然有序)。

如下演示遞歸的整個過程:

遞歸便是深度遍歷(如下由左至右進行遍歷):假設有這樣的一列數組{9,8,7,6,5,4,3,2,1}進行劃分的順序如下:

{9,8,7,6,5,4,3,2,1} --> {9,8,7,6,5},{4,3,2,1}

?

{9,8,7,6,5} --> {9,8,7},{6,5}

??????????????????????? {9,8,7} --> {9,8},{7}

????????????????????????????????????????? {9,8} --> {9},{8}

??????????????????????? {6,5} -->{6},{5}

?

{4,3,2,1} --> {4,3},{2,1}

????????????????????? {4,3} -->{4},{3}

????????????????????? {2,1} -->{2},{1}

?

當深度劃分到左右數組都只剩1個元素的時候,進行上述逆序的合并:

{9},{8} --> {8,9} 然后和 {7} --> {7,8,9}

??????????????????????????????? {6},{5} --> {5,6}??? 然后 {7,8,9}和{5,6} --> {5,6,7,8,9}

???????????????????????????????????? {2},{1} --> {1,2}

???????????????????????????????????? {4},{3} --> {3,4}?? 然后 {1,2}和 {3,4} --> {1,2,3,4}

???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????? 最終{5,6,7,8,9}和{1,2,3,4} --> {1,2,3,4,5,6,7,8,9}

?

具體實現代碼如下所示:

//歸并排序(目標數組,子表的起始位置,子表的終止位置)
private static void MergeSortFunction(int[] array, int first, int last)
{
try
{
if (first < last) //子表的長度大于1,則進入下面的遞歸處理
{
int mid = (first + last) / 2; //子表劃分的位置
MergeSortFunction(array, first, mid); //對劃分出來的左側子表進行遞歸劃分
MergeSortFunction(array, mid + 1, last); //對劃分出來的右側子表進行遞歸劃分
MergeSortCore(array, first, mid, last); //對左右子表進行有序的整合(歸并排序的核心部分)
}
}
catch (Exception ex)
{ }
}

//歸并排序的核心部分:將兩個有序的左右子表(以mid區分),合并成一個有序的表
private static void MergeSortCore(int[] array, int first, int mid, int last)
{
try
{
int indexA = first; //左側子表的起始位置
int indexB = mid + 1; //右側子表的起始位置
int[] temp = new int[last + 1]; //聲明數組(暫存左右子表的所有有序數列):長度等于左右子表的長度之和。
int tempIndex = 0;
while (indexA <= mid && indexB <= last) //進行左右子表的遍歷,如果其中有一個子表遍歷完,則跳出循環
{
if (array[indexA] <= array[indexB]) //此時左子表的數 <= 右子表的數
{
temp[tempIndex++] = array[indexA++]; //將左子表的數放入暫存數組中,遍歷左子表下標++
}
else//此時左子表的數 > 右子表的數
{
temp[tempIndex++] = array[indexB++]; //將右子表的數放入暫存數組中,遍歷右子表下標++
}
}
//有一側子表遍歷完后,跳出循環,將另外一側子表剩下的數一次放入暫存數組中(有序)
while (indexA <= mid)
{
temp[tempIndex++] = array[indexA++];
}
while (indexB <= last)
{
temp[tempIndex++] = array[indexB++];
}

//將暫存數組中有序的數列寫入目標數組的制定位置,使進行歸并的數組段有序
tempIndex = 0;
for (int i = first; i <= last; i++)
{
array[i] = temp[tempIndex++];
}
}
catch (Exception ex)
{ }
}



?

?????? 對于N個元素的數組來說, 如此劃分需要的層數是以2為底N的對數, 每一層中, 每一個元素都要復制到結果數組中, 并復制回來, 所以復制2N次, 那么對于歸并排序,它的時間復雜度為O(N*logN), 而比較次數會少得多, 最少需要N/2次,最多為N-1次, 所以平均比較次數在兩者之間. 它的主要問題還是在于在內存中需要雙倍的空間.

轉載于:https://www.cnblogs.com/kloseking/p/3165710.html

總結

以上是生活随笔為你收集整理的归并排序算法(C#实现)的全部內容,希望文章能夠幫你解決所遇到的問題。

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