归并排序和快速排序比较【算法设计与分析实验报告】

       下面的源代码是修改的了时间差精确到了纳秒级别的了,但是还是感觉很有误差。无论怎么测,总是快排比归并快,即使是测试数据的数组长度在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;
}



原文地址:https://www.cnblogs.com/freezhan/p/2974227.html