zoukankan      html  css  js  c++  java
  • 归并排序和快速排序比较【算法设计与分析实验报告】

           下面的源代码是修改的了时间差精确到了纳秒级别的了,但是还是感觉很有误差。无论怎么测,总是快排比归并快,即使是测试数据的数组长度在10以内。

            前面一样的程序写的是时间精确到微秒级的,数组长度大概在一万以内的,就是归并排序快了,大于这个长度的快速排序比较快。综合上面的情况,数组小时,二者时间差也不会太多,所以个人认为还是快速排序比较好了,唉还是觉得归并比较简单好写,弱爆了啊。。。

    #include<cstdio>
    #include<Windows.h>
    #include<ctime>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const int maxn = 100000000;     /* maxn 为数组最大值 */
    /*
    *a[]为随机产生的数组 , b[]复制随机数组,t[]用于归并排序,暂时保存a[]
    */
    int a[maxn];
    int b[maxn], t[maxn];
    int n;                        /* n为要比较的数的个数 */
    
    /*
    *对数组下标从 p到r之间的数进行排序
    *使得前面的数全都不大于基准元, 后面的数不小于基准元
    */
    int partition(int p, int r)
    {
        int i = p;
        int j = r+1;
        int x = a[p];
    
        while(true)
        {
            while(a[++i] < x && i < r);
            while(a[--j] > x);
    
            if(i >= j) break;
    
            //swap(a, i, j);
            int temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    
        a[p] = a[j];
        a[j] = x;
        return j; /* 返回基准元排好序后的位置 */
    }
    
    int randomizedPartition(int p, int r) /* 对基准元进行处理 */
    {
        int i = rand() % (r-p+1) + p; /* 产生p 到 q 之间的随机数 i */
    
        int temp = a[i];    /* 交换随机位置到开始位置,使其成为基准元 */
        a[i] = a[p];
        a[p] = temp;
    
        return partition(p, r);
    }
    
    void randomizedQuickSort(int p, int r) /* 快速排序 */
    {
        if(p < r)
        {
            int q = randomizedPartition(p, r); /* 分割 */
            randomizedQuickSort(p, q-1);      /* 从两边分别排序 */
            randomizedQuickSort(q+1, r);
        }
    }
    
    void merge_sort(int *a, int x, int y, int *t) /* 归并排序 */
    {
        if(y-x > 1)
        {
            int m = (y-x)/2 + x;       /* 取中间 */
            int p = x, q = m, i = x;
    
            merge_sort(b, p, m, t);   /* 两边分别排序 */
            merge_sort(b, m, y, t);
    
            while(p < m && q < y)
            {
                if(b[p] <= b[q]) t[i++] = b[p++];
                else t[i++] = b[q++];
            }
    
            while(p < m) t[i++] = b[p++];
            while(q < y) t[i++] = b[q++];
    
            for(i = x; i < y; i++) /* 将排序好的部分重新存入数组 a[]*/
                b[i] = t[i];
        }
    }
    
    int main()
    {
        printf("请输入要排序比较的个数 n ( n <= 100000000 ): ");
        while(scanf("%d", &n) != EOF)
        {
            LARGE_INTEGER begin, end;
            //double tstart, tend, MergeSortCost, QuickSortCost;
            long long  MergeSortCost, QuickSortCost;
    
            memset(a, 0, sizeof(a));       /* 清空数组为0 */
            for(int i = 0; i < n; i++)    /* 生成随机数 */
            {
                a[i] = rand();
                b[i] = a[i];
            }
    
            QueryPerformanceCounter(&begin); // tstart = clock();
            randomizedQuickSort(0, n-1); /* 快速排序 */
            QueryPerformanceCounter(&end); //tend = clock();
    
            QuickSortCost = end.QuadPart - begin.QuadPart; //tend - tstart;
            //for(int i = 0; i < n; i++) printf("%d ", a[i]);
    
    
            QueryPerformanceCounter(&begin); //tstart = clock();
            merge_sort(b, 0, n, t); /* 归并排序 */
            QueryPerformanceCounter(&end); //tend = clock();
    
            MergeSortCost = end.QuadPart - begin.QuadPart; //tend - tstart;
            //for(int i = 0; i < n; i++) printf("%d ", b[i]);
    
            printf("快速排序耗时:%lld ns,归并排序耗时:%lldns\n\n\n", QuickSortCost*100, MergeSortCost*100);
    
    
            printf("如果要继续比较请继续输入比较的个数 n : ");
    
        }
        return 0;
    }
    #include<cstdio>
    #include<Windows.h>
    #include<ctime>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    const int maxn = 100000000;     /* maxn 为数组最大值 */
    /*
    *a[]为随机产生的数组 , b[]复制随机数组,t[]用于归并排序,暂时保存a[]
    */
    int a[maxn];
    int b[maxn], t[maxn];
    int n;                        /* n为要比较的数的个数 */
    
    /*
    *对数组下标从 p到r之间的数进行排序
    *使得前面的数全都不大于基准元, 后面的数不小于基准元
    */
    int partition(int p, int r)
    {
        int i = p;
        int j = r+1;
        int x = a[p];
    
        while(true)
        {
            while(a[++i] < x && i < r);
            while(a[--j] > x);
    
            if(i >= j) break;
    
            //swap(a, i, j);
            int temp = a[i];
            a[i] = a[j];
            a[j] = temp;
        }
    
        a[p] = a[j];
        a[j] = x;
        return j; /* 返回基准元排好序后的位置 */
    }
    
    int randomizedPartition(int p, int r) /* 对基准元进行处理 */
    {
        int i = rand() % (r-p+1) + p; /* 产生p 到 q 之间的随机数 i */
    
        int temp = a[i];    /* 交换随机位置到开始位置,使其成为基准元 */
        a[i] = a[p];
        a[p] = temp;
    
        return partition(p, r);
    }
    
    void randomizedQuickSort(int p, int r) /* 快速排序 */
    {
        if(p < r)
        {
            int q = randomizedPartition(p, r); /* 分割 */
            randomizedQuickSort(p, q-1);      /* 从两边分别排序 */
            randomizedQuickSort(q+1, r);
        }
    }
    
    void merge_sort(int *a, int x, int y, int *t) /* 归并排序 */
    {
        if(y-x > 1)
        {
            int m = (y-x)/2 + x;       /* 取中间 */
            int p = x, q = m, i = x;
    
            merge_sort(b, p, m, t);   /* 两边分别排序 */
            merge_sort(b, m, y, t);
    
            while(p < m && q < y)
            {
                if(b[p] <= b[q]) t[i++] = b[p++];
                else t[i++] = b[q++];
            }
    
            while(p < m) t[i++] = b[p++];
            while(q < y) t[i++] = b[q++];
    
            for(i = x; i < y; i++) /* 将排序好的部分重新存入数组 a[]*/
                b[i] = t[i];
        }
    }
    
    int main()
    {
        printf("请输入要排序比较的个数 n ( n <= 100000000 ): ");
        while(scanf("%d", &n) != EOF)
        {
            LARGE_INTEGER begin, end;
            //double tstart, tend, MergeSortCost, QuickSortCost;
            long long  MergeSortCost, QuickSortCost;
    
            memset(a, 0, sizeof(a));       /* 清空数组为0 */
            for(int i = 0; i < n; i++)    /* 生成随机数 */
            {
                a[i] = rand();
                b[i] = a[i];
            }
    
            QueryPerformanceCounter(&begin); // tstart = clock();
            randomizedQuickSort(0, n-1); /* 快速排序 */
            QueryPerformanceCounter(&end); //tend = clock();
    
            QuickSortCost = end.QuadPart - begin.QuadPart; //tend - tstart;
            //for(int i = 0; i < n; i++) printf("%d ", a[i]);
    
    
            QueryPerformanceCounter(&begin); //tstart = clock();
            merge_sort(b, 0, n, t); /* 归并排序 */
            QueryPerformanceCounter(&end); //tend = clock();
    
            MergeSortCost = end.QuadPart - begin.QuadPart; //tend - tstart;
            //for(int i = 0; i < n; i++) printf("%d ", b[i]);
    
            printf("快速排序耗时:%lld ns,归并排序耗时:%lldns\n\n\n", QuickSortCost*100, MergeSortCost*100);
    
    
            printf("如果要继续比较请继续输入比较的个数 n : ");
    
        }
        return 0;
    }

    下面截个纳秒级别的,感觉不是很精确的图吧.

    通过此次算法分析两种排序方法的比较,我还学到了一些简单的头函数的使用.


    一、关于随机数的产生。

    /*
    *产生区间[a , b]之间的随机整数
    */
    #include<cstdio>
    #include<cstdlib>
    int main()
    {
        int a,b;
        while(scanf("%d%d", &a, &b) != EOF)
        {
            int ans = rand()%(b-a+1) + a;
            printf("%d\n", ans);
        }
        return 0;
        
    }


    二、如何测试系统当前时间。

    /*
    *微秒级时间测试
    */
    #include <time.h>  //time.h是C/C++中的日期和时间头文件
    #include<cstdio>
    #include<iostream>
    using namespace std;
    int main()
    {
        double tstart, tend, tcost;
    
        tstart = clock();
        for(int i=0;i<10000000;i++); //do something
            tend = clock();
        tcost = (double)(tend-tstart)/CLOCKS_PER_SEC;
    
        printf("%lf\n", tcost);
        cout<<CLOCKS_PER_SEC; // == 1000 ms
        return 0;
    }
    /*
    *纳秒级时间测试一 ,来自周杰学长
    */
    #include <Windows.h>
    #include <stdio.h>
    
    int main()
    {
        LARGE_INTEGER li;
        QueryPerformanceCounter(&li);
        printf("%lld\n", li);
        QueryPerformanceCounter(&li);
        printf("%lld\n", li);
        return 0;
    }

    /*
    *纳秒级时间测试二 :测试用时 ,来自周杰学长
    */
    #include <Windows.h>
    #include <stdio.h>
    
    int main()
    {
        LARGE_INTEGER begin, end;
        QueryPerformanceCounter(&begin);
        Sleep(0); // do something
        QueryPerformanceCounter(&end);
        long long duration = end.QuadPart - begin.QuadPart;
        printf("duration: %lldns\n", duration * 100);
        return 0;
    }



  • 相关阅读:
    记录阿里云服务器mysql被黑
    微服务SpringCloud容器化案例
    优雅的启动、停止、重启你的SpringBoot项目
    java模式:建造者模式
    java集合 线程安全
    挖坑:hive集成kerberos
    挖坑:handoop2.6 开启kerberos(全流程学习记录)
    Specified version of key is not available (44)
    Mysql数据按天分区,定期删除
    maven项目打包额外lib目录
  • 原文地址:https://www.cnblogs.com/freezhan/p/2974227.html
Copyright © 2011-2022 走看看