排序演算法 歸併排序

2021-08-08 22:05:46 字數 2065 閱讀 9937

歸併排序的定義:

歸併排序演算法採用的是分治演算法,即把兩個(或兩個以上)有序表合併成乙個新的有序表,即把待排序的序列分成若干個子串行,每個子串行都是有序的,然後把有序子串行合併成整體有序序列,這個過程也稱為2-路歸併.注意

:歸併排序的一種穩定排序

,即相等元素的順

序不會改變

.

大致過程:

歸併排序的時間複雜度

歸併排序的最好、最壞和平均時間複雜度都是

o(nlogn)

,而空間複雜度是

o(n)

附上**:

void msort(int a, int len)

void msort_part(int *a, int*tmp, int low, int high)

}void merge(int *a, int *tmp, int low, int mid, int high)

while (low <= mid)//左序列剩下未歸併的直接複製過去

tmp[des++] = a[low++];

while (low2 <= high)//右序列剩下未歸併的直接複製過去

tmp[des++] = a[low2++];

while (t <= high)//將排序好的序列賦值回原陣列,用到了之前的t }

void main()

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

msort(a,9);

putchar(10);

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

getchar();

}

非遞迴實現:非遞迴版的歸併排序,省略了中間的棧空間,直接申請一段o(n)的位址空間即可,因此空間複雜度為o(n),時間複雜度為o(nlogn);

開始以間隔為1的進行歸併,也就是說,第乙個元素跟第二個進行歸併。第三個與第四個進行歸併;

然後,再以間隔為2的進行歸併,1-4進行歸併,5-8進行歸併;

再以2*2的間隔,同理,知道2*k超過陣列長度為止。

/*

演算法思想:

開始以間隔為1的進行歸併,也就是說,第乙個元素跟第二個進行歸併。

第三個與第四個進行歸併;

然後,再以間隔為2的進行歸併,1-4進行歸併,5-8進行歸併;

再以2*2的間隔,同理,知道2*k超過陣列長度為止。

*/void mergesort(int *arr, int length)

}void merge(int *arr1, int *temp, int k, int length)

//如過剩餘個數比乙個k長度還多...那麼就在進行一次合併

if (i < length - k + 1)

sort(arr1, temp, i, i + k - 1, length - 1);

else

for (j = i; j < length; j++)

temp[j] = arr1[j];

//複製回原陣列

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

arr1[i] = temp[i];

}void sort(int *arr3, int *arr1, int begin, int m, int end)

if (i <= m)

else

}

排序演算法 歸併排序

歸併排序是建立在歸併操作上的一種有效的排序演算法。該演算法是採用分治法 divide and conquer 的乙個非常典型的應用。首先考慮下如何將將二個有序數列合併。這個非常簡單,只要從比較二個數列的第乙個數,誰小就先取誰,取了後就在對應數列中刪除這個數。然後再進行比較,如果有數列為空,那直接將另...

排序演算法 歸併排序

include include define status int define max 20 typedef struct elemtype typedef struct sqlist void inital sqlist l 初始化 bool lt int i,int j void merge ...

排序演算法 歸併排序

歸併排序的思想其實完全是分治法的思想的體現,它完全遵循分治法的模式。這裡有必要再重提下分治法的思想 將原有的問題分解為幾個規模較小的但類似於原問題的子問題,遞迴的求解這些子問題,然後再合併這些子問題的解來求得原問題的解。現在來看看歸併排序的操作 1 將等待排序的含有 n 個元素的序列分解成各具有 n...