排序---歸併排序

1.  歸併排序html

歸併排序(Merge sort),是建立在歸併操做上的一種有效的排序算法,效率爲O(nlogn)。該算法是採用分治法(Divide and Conquer)的一個很是典型的應用,且各層分治遞歸能夠同時進行。【詳情見維基百科ios

歸併排序
Merge-sort-example-300px.gif
分類 排序算法
數據結構 數組
最壞時間複雜度 \Theta (n\log n)
最優時間複雜度 \Theta (n\log n)
平均時間複雜度 \Theta (n\log n)
最壞空間複雜度 \Theta(n)

2. 歸併排序(非遞歸版)C++ 實現算法

 1 #include<iostream>
 2 #include<vector>
 3 using namespace std;
 4 
 5 void MergeSort(vector<int> &array){
 6     int len = array.size();
 7     vector<int> temp(len);
 8 
 9     for(int seg = 1; seg <= len; seg = 2 * seg){
10         // 將array中相鄰長度爲seg的子序列兩兩歸併到temp
11         for(int start = 0; start <= len; start = start + 2 * seg){
12             // 肯定歸併範圍 low, mid, high
13             int low = start;
14             int mid = min(len - 1, start + seg - 1);
15             int high = min(len - 1, start + 2 * seg - 1);
16 
17             int start1 = low, end1 = mid;
18             int start2 = mid+1, end2 = high;
19             int idx = low;
20 
21             // 將array[low...mid]和array[mid+1...high]歸併到temp[low...high]
22             while(start1 <= end1 && start2 <= end2)
23                 temp[idx++] = array[start1] < array[start2]? array[start1++] : array[start2++];
24             while(start1 <= end1)
25                 temp[idx++] = array[start1++];
26             while(start2 <= end2)
27                 temp[idx++] = array[start2++];
28         }
29         // 將temp賦值給array,重新進行下一輪
30         int i = 0;
31         for(vector<int>::iterator it = temp.begin(); it != temp.end(); it++){
32             array[i++] = *it;
33         }
34     }
35 }
36 
37 bool Check(vector<int> arr){
38     bool flag = true;
39     for(int i=1; i<arr.size(); i++)
40         flag = flag && (arr[i]-arr[i-1] >= 0);
41     return flag;
42 }
43 
44 int main(int argc, char const *argv[])
45 {
46     vector<int> arr = {5, 9, 0, 1, 3, 6, 4, 8, 2, 7};
47 
48     MergeSort(arr);
49     for(auto &it : arr)
50         cout<<it<<' ';
51     cout<<endl;
52 
53     // 判斷返回結果的正確性
54     bool isInOrder = Check(arr);
55     if (isInOrder)
56         cout<<"true"<<endl;
57     else
58         cout<<"false"<<endl;
59     return 0;
60 }

 

3. 使用大量隨機數據測試數組

#include<iostream>
#include<vector>
#include<stdlib.h>
#include<time.h>
using namespace std;

void MergeSort(vector<int> &array) {
    int len = array.size();
    vector<int> temp(len);

    for (int seg = 1; seg < len; seg = 2 * seg) {
        for (int start = 0; start < len; start += 2 * seg) {
            int low = start;
            int mid = min(start + seg - 1, len-1);
            int high = min(start + 2 * seg-1, len-1);

            int i = low, j = mid + 1;
            for(int k = low; k <= high; k++)
                temp[k] = array[k];

            for(int idx = low; idx <= high; idx++){
                if(i > mid)
                    array[idx] = temp[j++];
                else if(j > high)
                    array[idx] = temp[i++];
                else if(temp[i] < temp[j])
                    array[idx] = temp[i++];
                else
                    array[idx] = temp[j++];
            }
        }
    }
}

// 判斷array是否有序
bool isOrder(vector<int> &array){
    for(int i = 1; i < array.size(); i++){
        if(array[i] < array[i-1])
            return false;
    }
    return true;
}

// 生成n個介於min,max之間的整型數
vector<int> RAND(int max, int min, int n) {
    vector<int> res;
    srand(time(NULL)); // 註釋該行以後,每次生成的隨機數都同樣
    for(int i = 0; i < n; ++i) {
        int u = (double)rand() / (RAND_MAX + 1) * (max - min) + min;
        res.push_back(u);
    }
    return res;
}

// 使用20000000個介於1,10000之間的數據進行測試
int main(int argc, char const *argv[]) {
    vector<int> a = RAND(1, 10000, 20000000);

    clock_t start = clock();
    MergeSort(a);
    clock_t end   = clock();
    cout << "Time goes: " << (double)(end - start) / CLOCKS_PER_SEC << "sec" << endl;

    bool sorted = isOrder(a);
    cout<<sorted<<endl;
    return 0;
}

運行結果:對2千萬隨機數據排序耗時13.516sec數據結構

Time goes: 13.516sec
1
[Finished in 15.7s]

 【點擊此處查看經常使用排序算法ide

相關文章
相關標籤/搜索