歸併排序和快速排序類似,都是基於分治的,步驟如下:
(1)確定待排序陣列的分界點mid, 一般取mid為待排序陣列的中位數 mid = l + r >> 1;
(2)遞迴排序分界點的左右兩側區間,直到區間大小為1;
(3)歸併兩個排好序的區間,把兩個有序的陣列合二為一,最後合併好的陣列就是排好序的陣列。
歸併的方法是雙指標。
左右區間排好序的陣列分別為left和right,我們開乙個額外的,大小與原陣列大小相等的陣列tmp記錄最後排好序的結果。
用兩個指標i和j分別指向left和right的開頭,指向的數就是兩個陣列中的最小值,把這兩個值進行比較,較小的那個數就是所有數的最小值,
把這個最小值加入到tmp陣列中,然後對應的指標向後移動一位,指向陣列剩下部分的數中的最小值。
重複這個步驟直到某個指標走到了終點,此時另乙個指標走到了一半,退出迴圈,把未走完的剩餘部分加到答案陣列tmp中。
如果兩個指標指向的數相同,我們把第乙個數放到tmp陣列中,所以歸併排序之後相同數字的相對順序與原陣列中的相對順序相同,因此歸併排序是穩定的。
時間複雜度分析:歸併排序每次把當前當前陣列劃分為兩個長度為一半的子陣列,並進行排序,直到劃分的陣列大小為1.
比如原陣列大小為n,第一次劃分為兩個大小為n/2的子陣列進行排序,第二次劃分出4個大小為n/4,。。。。這樣,一共要劃分n次。
每一次都要對n個數進行排序,所以每次歸併都是o(n)的乙個複雜度。
所以歸併排序總的時間複雜度是o(nlogn)。
**如下:
#includeusing namespace std;
const int n = 1e6 + 10;
int q[n], tmp[n];
void merge_sort(int q, int l, int r)
int mid = l + r >> 1;
merge_sort(q, l, mid); //遞迴歸併左右兩部分
merge_sort(q, mid + 1, r);
int k = 0, i = l, j = mid + 1; //k記錄當前tmp陣列中已經放好位置的是第幾個數
while(i <= mid && j <= r) else
}while(i <= mid)
while(j <= r)
for(int i = l, j = 0; i <= r; ++i, ++j)
}int main()
merge_sort(q, 0, n - 1);
for(int i = 0; i < n; ++i)
return 0;
}
歸併排序模板
歸併 將兩個或兩個以上的有序表組合成乙個新的有序表。一般情況不用這種方式排序,只有在將多個有序序列整合成乙個有序序列是才會用到歸併排序,才能想歸併效率體現的最高。演算法描敘 1 設初始序列含有n個記錄,則可看成n個有序的子串行,每個子串行長度為1。2 兩兩合併,得到 n 2 個長度為2或1的有序子串...
歸併排序模板
歸併排序主要的思想是分治和合併,合併我覺得挺好理解的,分治是用遞迴實現的感覺不太好理解,我就貼乙個模板,拿著就能用了。要是像仔細學習了解歸併排序的話可以看下這篇文章傳送門,感覺講的不能再詳細了。歸併排序模板 include include include include include define...
歸併排序模板
思路 每次把陣列分成兩部分,一直遞迴下去,當分成最少長度後,開始從最底層向上歸併相鄰的兩段陣列。時間複雜度o n log n include include include using namespace std void merge int a,int left,int right,int mid...