歸併排序(遞迴與非遞迴)的實現

2021-07-05 01:37:30 字數 1546 閱讀 6682

摘要:

(1)歸併排序幾乎以o(nlogn)的時間界實現,是典型的分治演算法;

(2)歸併排序的基本思路很簡單:就是將目標序列分為兩個部分,將兩個子串行排序好之後,再將它們合併。注意到合併兩個已排序的序列只需要o(n)的時間界。

(3)對兩個子串行的排序顯然也是通過遞迴的歸併排序實現的。

(4)需要注意的乙個小細節是,當子串行的元素很少時,繼續呼叫歸併排序未必是一件划算的事.因此可以設定乙個邊界,當元素個數少於這個值時就掉用最簡單的插入排序.

合併的過程

合併的過程相對簡單,用兩個指標指向兩個子串行的開始點,然後比較它們的大小.將較小的乙個放入新的陣列.然後將指向較小元素的指標前移一位。繼續這個過程直到某乙個指標達到邊界.然後將另乙個子串行的剩餘所有元素都置入新的陣列.

注意的細節:如果每一次遞迴都建立乙個新的陣列那麼將會占用很多的空間.因此合理的做法是在進入遞迴之前建立兩個陣列,然後用兩個變數left,right標誌子串行的邊界。每一次合併的過程都是把a[left1]到a[right1],a[left1+1]到a[right2]合併到b[left1]到b[right2];

#include "stdafx.h"

#include "malloc.h"

#include "stdlib.h"

#include "string.h"

#define max 10000000

int min(int a ,int b)

void merge(int *a,int *tmp,int left1,int right1,int left2, int right2)

while(point1 <= right1)

tmp[left1 ++] = a[point1++];

while(point2 <= right2)

tmp[left1++] = a[point2++];

for (left1 = k;left1<= right2;left1++)

}

真正的排序

void mergesort(int *a,int *tmp,int left,int right)

以上的程式都是用遞迴的辦法實現。下面用非遞迴的辦法實現歸併排序.

非遞迴的基本思路

(1)我們應該每次對2^i長度的子串行進行合併。例如最開始對長度為1的相鄰子串行進行合併;然後對長度為2的相鄰的子串行進行合併。**如下

void mergesort2(int *a,int *tmp,int n)

if (i <= n-1)

number *= 2;

}}void msort(int a,int n)

cutoff = i - n;

int *b = (int *)malloc(sizeof(int)*i);

int *tmp = (int *)malloc(sizeof(a)*n);

mergesort2(a,tmp,n);

free(tmp);

}

歸併排序 遞迴與非遞迴實現

歸併排序 採用的是一種分而治之的思想.過程 將乙個陣列進行二分,直到有每組有乙個元素為止.然後進行合併元素,按照一定的順序進行排序.實現 遞迴實現 void merge int arr,int left,int mid,int right,int tmp int start left int end...

歸併排序遞迴與非遞迴實現

基本思路 歸併排序 merge sort 是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。歸併排序遞迴體,把整個序列遞迴分為兩個長度為1的子...

歸併排序(遞迴與非遞迴)

1.遞迴 把序列分成元素個數盡量相等的兩部分,再將兩半分別排序,合併有序的兩個序列 遞迴 void merge sort int a,int low,int heigh,int t a為待排序陣列,low,high分別為a的上下限 0 n 1 t為輔助陣列 for i low,j 0 i heigh...