數(shù)據(jù)結(jié)構(gòu)之歸并排序的實(shí)例詳解
歸并排序
基本思想
歸并排序是建立在二路歸并和分治法的基礎(chǔ)上的一個(gè)高效排序算法,將已有序的子序列合并,得到完全有序的序列;即先使每個(gè)子序
列有序,再使子序列段間有序。若將兩個(gè)有序表合并成一個(gè)有序表,稱為二路歸并。
將待排序序列R[0...n-1]看成是n個(gè)長(zhǎng)度為1的有序序列,將相鄰的有序表成對(duì)歸并,得到n/2個(gè)長(zhǎng)度為2的有序表;將這些有序序列
再次歸并,得到n/4個(gè)長(zhǎng)度為4的有序序列;如此反復(fù)進(jìn)行下去,最后得到一個(gè)長(zhǎng)度為n的有序序列。所以呢,我們總結(jié)一下歸并排序
其實(shí)就只有兩步:
分解:將有序序列不斷地分裂,直到每個(gè)區(qū)間都只有一個(gè)數(shù)據(jù)為止.
合并:將兩個(gè)區(qū)間合并為一個(gè)有序的區(qū)間,一直合并知道只有一個(gè)區(qū)間為止.
圖是我偷來(lái)的,但是學(xué)習(xí)是認(rèn)真的.
分解的過(guò)程我們很容易想明白的,用遞歸就可以.但是我們今天最主要的步驟是合并,你要將兩個(gè)區(qū)間合并為一個(gè)有序的區(qū)間你會(huì)怎么思考呢?
這個(gè)非常簡(jiǎn)單,只要從比較二個(gè)數(shù)列的第一個(gè)數(shù),誰(shuí)小就先取誰(shuí),取了后就在對(duì)應(yīng)數(shù)列中刪除這個(gè)數(shù)。然后再進(jìn)行比較,如果有數(shù)
列為空,那直接將另一個(gè)數(shù)列的數(shù)據(jù)依次取出即可。
代碼實(shí)現(xiàn):
//將有序數(shù)組a[]和b[]合并到c[]中
void MemeryArray(int a[], int n, int b[], int m, int c[])
{
int i, j, k;
i = j = k = 0;
while (i < n && j < m)
{
if (a[i] < b[j])
c[k++] = a[i++];
else
c[k++] = b[j++];
}
while (i < n)
c[k++] = a[i++];
while (j < m)
c[k++] = b[j++];
}
其實(shí)我們發(fā)現(xiàn)這種做法效率其實(shí)還是蠻高的,效率達(dá)到了O(N).現(xiàn)在我們解決了合并的問(wèn)題.
現(xiàn)在總的來(lái)看一下歸并排序的做法,通過(guò)先遞歸的分解數(shù)列(將數(shù)列分解成只有一個(gè)元素的區(qū)間),再合并數(shù)列就完成了歸并排序。
代碼實(shí)現(xiàn)
//將有二個(gè)有序數(shù)列a[first...mid]和a[mid...last]合并。
void mergearray(int a[], int first, int mid, int last, int temp[])
{
int i = first, j = mid + 1;
int m = mid, n = last;
int k = 0;
while (i <= m && j <= n)
{
if (a[i] <= a[j])
temp[k++] = a[i++];
else
temp[k++] = a[j++];
}
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];
}
void mergesort(int a[], int first, int last, int temp[])
{
if (first < last)
{
int mid = (first + last) / 2;
mergesort(a, first, mid, temp); //左邊有序
mergesort(a, mid + 1, last, temp); //右邊有序
mergearray(a, first, mid, last, temp); //再將二個(gè)有序數(shù)列合并
}
}
bool MergeSort(int a[], int n)
{
int *p = new int[n];
if (p == NULL)
return false;
mergesort(a, 0, n - 1, p);
delete[] p;
return true;
}
總結(jié)
歸并排序的效率是比較高的,設(shè)數(shù)列長(zhǎng)為N,將數(shù)列分開成小數(shù)列一共要logN步,每步都是一個(gè)合并有序數(shù)列的過(guò)程,時(shí)間復(fù)雜度
可以記為O(N),故一共為O(N*logN)。因?yàn)闅w并排序每次都是在相鄰的數(shù)據(jù)中進(jìn)行操作,所以歸并排序在O(N*logN)的幾種排序方
法(快速排序,歸并排序,希爾排序,堆排序)也是效率比較高的。
算法名稱 最差時(shí)間復(fù)雜度 平均時(shí)間復(fù)雜度 最優(yōu)時(shí)間復(fù)雜度 空間復(fù)雜度 穩(wěn)定性
歸并排序 O(NlogN) O(NlogN) O(NlogN) O(n) 穩(wěn)定
所有排序當(dāng)中用的最多的就是堆排序,快速排序,歸并排序.
若從空間復(fù)雜度來(lái)考慮:首選堆排序,其次是快速排序,最后是歸并排序。
若從穩(wěn)定性來(lái)考慮,應(yīng)選取歸并排序,因?yàn)槎雅判蚝涂焖倥判蚨际遣环€(wěn)定的。
若從平均情況下的排序速度考慮,應(yīng)該選擇快速排序。
以上就是數(shù)據(jù)結(jié)構(gòu)中歸并排序的實(shí)例詳解,如有疑問(wèn)請(qǐng)留言或者到本站社區(qū)交流討論,感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
上一篇:C++ 中類對(duì)象類型的轉(zhuǎn)化的實(shí)例詳解
欄 目:C語(yǔ)言
下一篇:詳解C++中十六進(jìn)制字符串轉(zhuǎn)數(shù)字(數(shù)值)
本文標(biāo)題:數(shù)據(jù)結(jié)構(gòu)之歸并排序的實(shí)例詳解
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/1208.html
您可能感興趣的文章
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)- 解析最少換車次數(shù)的問(wèn)題詳解
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-用棧實(shí)現(xiàn)表達(dá)式求值的方法詳解
- 01-10APUE筆記之:進(jìn)程環(huán)境詳解
- 01-10內(nèi)部排序之堆排序的實(shí)現(xiàn)詳解
- 01-10進(jìn)程間通信之深入消息隊(duì)列的詳解
- 01-10海量數(shù)據(jù)處理系列之:用C++實(shí)現(xiàn)Bitmap算法
- 01-10如何求連續(xù)幾個(gè)數(shù)之和的最大值
- 01-10C++算法之海量數(shù)據(jù)處理方法的總結(jié)分析
- 01-10深入理解c++中char*與wchar_t*與string以及wstring之間的相互轉(zhuǎn)換
- 01-10用代碼和UML圖化解設(shè)計(jì)模式之橋接模式的深入分析


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文


