歸併排序的定義:
歸併排序演算法採用的是分治演算法,即把兩個(或兩個以上)有序表合併成乙個新的有序表,即把待排序的序列分成若干個子串行,每個子串行都是有序的,然後把有序子串行合併成整體有序序列,這個過程也稱為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...