zoukankan      html  css  js  c++  java
  • 排序---归并排序

    1.  归并排序

    归并排序(Merge sort),是创建在归并操作上的一种有效的排序算法,效率为O(nlogn)。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用,且各层分治递归可以同时进行。【详情见维基百科

    归并排序
    Merge-sort-example-300px.gif
    分类 排序算法
    数据结构 数组
    最坏时间复杂度 Theta (nlog n)
    最优时间复杂度 Theta (nlog n)
    平均时间复杂度 Theta (nlog 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]

     【点击此处查看常用排序算法

  • 相关阅读:
    Java学习笔记七:Java的流程控制语句之switch
    Java学习笔记六:Java的流程控制语句之if语句
    Java学习笔记五:Java中常用的运算符
    如何在linux下使用git管理上传代码&误删文件修复
    pwnable.tw applestore 分析
    pwnable.tw dubblesort 分析
    word中如何只修改英文的颜色
    word中图片遮挡文字怎么办
    angr进阶(6)绕过反调试
    angr进阶(5)内存操作
  • 原文地址:https://www.cnblogs.com/iwangzhengchao/p/9950550.html
Copyright © 2011-2022 走看看