2023年,約翰·馮·諾依曼(john von neumann)發明了歸併排序,這是典型的分治演算法的應用。
歸併排序(merge sort)是建立在歸併操作上的一種有效的排序演算法,該演算法是採用分治法(divide and conquer)的乙個非常典型的應用。將已有序的子串行合併,得到完全有序的序列;即先使每個子串行有序,再使子串行段間有序。
歸併排序演算法有兩個基本的操作,乙個是分,也就是把原陣列劃分成兩個子陣列的過程。另乙個是治,它將兩個有序陣列合併成乙個更大的有序陣列。
將待排序的線性表不斷地切分成若干個子表,直到每個子表只包含乙個元素,這時,可以認為只包含乙個元素的子表是有序表。
將子表兩兩合併,每合併一次,就會產生乙個新的且更長的有序表,重複這一步驟,直到最後只剩下乙個子表,這個子表就是排好序的線性表。
假設我們有乙個初始數列為,整個歸併排序的過程如下圖所示。
可以看到這種結構很像一棵完全二叉樹,本文的歸併排序我們採用遞迴去實現(也可採用迭代的方式去實現)。分階段可以理解為就是遞迴拆分子序列的過程,遞迴深度為log2n。
再來看看治階段,我們需要將兩個已經有序的子串行合併成乙個有序序列,比如上圖中的最後一次合併,要將[4,5,7,8]和[1,2,3,6]兩個已經有序的子串行,合併為最終序列[1,2,3,4,5,6,7,8],來看下實現步驟。
速度僅次於快速排序。
o(nlogn)。
o(n),歸併排序需要乙個與原陣列相同長度的陣列做輔助來排序。
穩定。
void merge(int sourcearr,int temparr, int startindex, int midindex, int endindex)
while(i != midindex+1)
temparr[k++] = sourcearr[i++];
while(j != endindex+1)
temparr[k++] = sourcearr[j++];
for(i=startindex; i<=endindex; i++)
sourcearr[i] = temparr[i];}
//內部使用遞迴
void mergesort(int sourcearr, int temparr, int startindex, int endindex)
}int main(int argc, char * ar**) ;
int i, b[8];
mergesort(a, b, 0, 7);
for(i=0; i<8; i++)
printf("%d ", a[i]);
printf("\n");
return 0;
}
package mergesort;
public class mergesort ;
int mid = l + (h - l) / 2;
int leftarr = mergesort(nums, l, mid); //左有序陣列
int rightarr = mergesort(nums, mid + 1, h); //右有序陣列
int newnum = new int[leftarr.length + rightarr.length]; //新有序陣列
int m = 0, i = 0, j = 0;
while (i < leftarr.length && j < rightarr.length)
while (i < leftarr.length)
newnum[m++] = leftarr[i++];
while (j < rightarr.length)
newnum[m++] = rightarr[j++];
return newnum;
}public static void main(string args) ;
int newnums = mergesort(nums, 0, nums.length - 1);
for (int x : newnums) }}
def mergesort(lists):
if len(lists) <= 1:
return lists
num = int( len(lists) / 2 )
left = mergesort(lists[:num])
right = mergesort(lists[num:])
return merge(left, right)
def merge(left,right):
r, l=0, 0
result=
while l
if left[l] <= right[r]:
l += 1
else:
r += 1
result += list(left[l:])
result += list(right[r:])
return result
print mergesort([1, 2, 3, 4, 5, 6, 7, 90, 21, 23, 45])
排序 歸併排序 merge sort
將已有序的子串行合併,得到完全有序的序列 即先使每個子串行有序,再使子串行段間有序。若將兩個有序表合併成乙個有序表,稱為二路歸併。nlogn 演示 演示 c 題目描述 給定你乙個長度為n的整數數列。請你使用歸併排序對這個數列按照從小到大進行排序。並將排好序的數列按順序輸出。輸入格式 輸入共兩行,第一...
歸併排序 Merge sort
merge the a s.m and a m 1.t to r s.t template void two merge typet a,typet r,int s,int m,int t while i m r k a i while j t r k a j merge the a 0.n 1 s...
歸併排序(merge sort)
歸併排序 歸併排序是一種遞迴排序演算法,無論陣列元素的原始順序如何,其效能恆定不變。將陣列一分為二,分別排序兩部分元素,再將有序的兩半陣列歸併為乙個有序陣列。歸併步驟比較陣列前一半的元素與陣列的後一半元素,並將較小元素移到臨時陣列,該過程繼續前進,直到其中一半再沒有元素為止。此後只需將其餘元素移到臨...