| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6193 人关注过本帖, 3 人收藏
标题:几种排序算法效率比较
只看楼主 加入收藏
long0042
Rank: 2
等 级:论坛游民
帖 子:38
专家分:50
注 册:2008-3-5
结帖率:100%
收藏(3)
已结贴  问题点数:20 回复次数:13 
几种排序算法效率比较
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>

#define NUM 1024*10

void swap(int *p, int *q)
{
    int tmp = *p;
    *p = *q;
    *q = tmp;
}

//////////////////选择排序///////////////////
void selectSort(int *p, int num)
{
    for (int i = 0; i < num; i++)
    {
        int min = p[i];
        int minindex = i;

        for (int j = i; j < num; j++)
        {
            if (min > p[j])
            {
                min = p[j];
                minindex = j;
            }
        }

        swap(&p[minindex], &p[i]);
    }
}
////////////////////////////////////////////////


///////////////////快速排序/////////////////////
int getSort(int *p, int min, int max)
{
    int i = min;
    int j = max;
    int key = p[min];

    while (1)
    {
        for (; ; j--)
        {
            if (i == j)
                return i;

            if (p[j] < key)
            {
                swap(&p[i], &p[j]);
                i++;
                break;
            }
        }

        for (; ; i++)
        {
            if (i == j)
                return i;

            if (p[i] > key)
            {
                swap(&p[i], &p[j]);
                j--;
                break;
            }
        }
    }

    return -1;
}

void quickSort(int *p, int min, int max)
{
    if (min >= max)
        return ;

    int i = getSort(p, min, max);
    if (i < 0)
        return ;

    quickSort(p, min, i-1);
    quickSort(p, i+1, max);
}

void quickSort2(int *p, int min, int max)
{
    if (min >= max)
        return ;

    int i = min;
    int j = max;
    int key = (p[min]+p[min+1])/2;
    int iIndex = i, jIndex = j;

    while (1)
    {
        if (i == j)
            break;

        for (;; j--)
        {
            if (p[j] < key)
            {
                iIndex = j;
                break;
            }
            if (i == j)
                break;
        }

        for (;; i++)
        {
            if (p[i] >= key)
            {
                jIndex = i;
                swap(&p[jIndex], &p[iIndex]);
                break;
            }
            if (i == j)
                break;
        }
    }

    quickSort2(p, min, i);
    quickSort2(p, i+1, max);
}
///////////////////////////////////////////////


///////////////////堆排序//////////////////////
void dealHeap(int *p, int index, int count)
{
    if (2*index + 2 > count)
        return ;

    int left = 2*index + 1;
    int right = 2*index + 2;

    int m = p[left] > p[right] ? left : right;

    if (p[m] > p[index])
    {
        swap(&p[m], &p[index]);
        dealHeap(p, m, count);
    }
}

void createHeap(int *p, int count)
{
    for (int i = count; i >= 0; i--)
    {
        dealHeap(p, i, count);
    }
}

void heapSort(int *p, int count)
{
    createHeap(p, count);

    for (int i = count; i >= 0; i--)
    {        
        dealHeap(p, 0, i);
        if (i != 1)
            swap(&p[0], &p[i]);
    }
}
//////////////////////////////////////////////////////


void writeData(int *buffer)
{
    for (int i = 0; i < NUM; i++)
    {
        buffer[i] = rand()%20000 + 1;
    }

    FILE *fp = fopen("data.dat", "wb");
    fwrite(buffer, sizeof(int), NUM, fp);
    fclose(fp);
}

void readData(int *buffer)
{
    FILE *fp = fopen("data.dat", "rb");
    fread(buffer, sizeof(int), NUM, fp);
    fclose(fp);
}


void usageMessage()
{
    printf("1选择排序\n");
    printf("2快速排序\n");
    printf("3堆排序\n");
    printf("q退出\n");
}

int main()
{
    int *buffer = (int *)malloc(sizeof(int) * NUM);
    writeData(buffer);
    usageMessage();

    int over = 1;
    while (over)
    {
        readData(buffer);

        float start;
        switch(getche())
        {
        case '1':
            {
                start = clock()/1000.0f;
                selectSort(buffer, NUM);
                float end = clock()/1000.0f;
                printf("\t选择排序 using time: %f\n", end-start);
                break;
            };
        case '2':
            {
                start = clock()/1000.0f;
                quickSort(buffer, 0, NUM-1);
                float end = clock()/1000.0f;
                printf("\t快速排序 using time: %f\n", end-start);
                break;
            }
        case '3':
            {
                start = clock()/1000.0f;
                heapSort(buffer, NUM-1);
                float end = clock()/1000.0f;
                printf("\t堆排序 using time: %f\n", end-start);
                break;
            }
        case 'q':
            {
                //exit
                over = 0;
            }
        }
    }

    free(buffer);

    return 0;
}

1、通过三种算法的比较,当数据量大的时候,快速排序用时最短。数据量少的时候差别基本上不大。
2、这三种算法都不是很适合数据整体是顺序的情况、这个时候情况不理想。可以选择插入排序等来替换(有时间写一个测试一下)
3、从网上的理论上讲,堆排序在数据量很大的时候要优于快速排序。我这里堆排序总是稍微比快速排序慢一点点, 是不是堆排序写的有问题呢?

通过设置NUM宏的值来对数据量不同的情况进行测试。编译环境vs2008 + win7
搜索更多相关主题的帖子: 算法 1024 include 
2012-07-20 21:12
奋斗猪
Rank: 2
来 自:奋斗的途中
等 级:论坛游民
帖 子:43
专家分:91
注 册:2012-7-4
收藏
得分:10 
标记前来学习,感谢分享

贵在坚持!
2012-07-20 22:01
netlin
Rank: 13Rank: 13Rank: 13Rank: 13
等 级:贵宾
威 望:24
帖 子:544
专家分:4308
注 册:2012-4-9
收藏
得分:10 
学习了!

做自己喜欢的事!
2012-07-21 11:42
long0042
Rank: 2
等 级:论坛游民
帖 子:38
专家分:50
注 册:2008-3-5
收藏
得分:0 
貌似大家对这种东东没什么兴趣啊。呵呵
2012-07-25 16:00
zklhp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:china
等 级:贵宾
威 望:254
帖 子:11485
专家分:33241
注 册:2007-7-10
收藏
得分:0 
貌似数据结构的书里面对排序算法的时间复杂度等东西有很讨论罢
2012-07-25 16:05
long0042
Rank: 2
等 级:论坛游民
帖 子:38
专家分:50
注 册:2008-3-5
收藏
得分:0 
回复 5楼 zklhp
我知道,数据结构里面说了一大堆。但那毕竟是理论,在实践中是不一样的。
不同的编译器,不同的平台,不同的人写的代码和优化的方法,可能都会造成差异。
本来想看看又没有人有好的优化方法或者是指明我不足的地方。
网上还说堆排序大数据的时候比快速排序快呢,我怎么写不出来。我这里只能证明快速排序更好些。
2012-07-25 16:11
zjy83350535
Rank: 1
等 级:新手上路
帖 子:4
专家分:5
注 册:2012-7-24
收藏
得分:0 
选择排序 平均时间复杂度 O(N^2),对数据有序性不敏感,比较次数多,交换次数较少   
快速排序 平均时间复杂度 O(Nlog N),不是稳定的排序.如果每次都能均匀划分序列,排列速度是最快的.
堆排序..涉及到二叉树了 没怎么接触过  不知道
2012-07-25 17:18
qq383264679
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:155
专家分:130
注 册:2012-1-19
收藏
得分:0 
当排好序的一个数组里
  用二分法排好序最快吧
例子一个从小到大排好的序
do
{
  mid = (head + stil) / 2;
  if (key == a[mid]
      printf("该数的下标是%d",min);
  else if (key > a[min])
      head = mid + 1;
 else
      stil = mid -1;
}while(head <= stil)
2012-07-25 17:20
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
我写的堆排你可以拿去测测。但其实我觉得如果算法一致的话,效率不会有太大差别。
你把测试结果也一并公布出来,让我们看看它们花费的时间大约是个什么差距。本来你用随机数据测就应该是快排最有效,理论和实践都表明快排是现有排序算法中表现最好的一个。
堆排的优势是稳定,主要是指,它只需要 O(1) 的辅助空间就可以完成 O(n logn) 的排序。而快排递归是有代价的,而且有时会有恶化成 O(n^2) 的倾向。在极端的情况下,对稳定性或者对资源有严格的限制,一般都倾向认为堆排是比快排更好的选择。
程序代码:
void heap_sort(int a[], int n)
{
    int i, c, r, t;
    if (n < 2) return;

    /* make heap */
    for (i = (n-1) / 2; i >= 0; i--)
    {
        for (c = i; 2 * c + 1 < n; c = r) {
            r = 2 * c + 1;
            if (r+1 < n && a[r] < a[r+1]) ++r;
            if (a[c] >= a[r]) break;
            t = a[c]; a[c] = a[r]; a[r] = t;
        }
    }
    /* sort heap */
    for (i = n-1; i > 0; i--)
    {
        t = a[i]; a[i] = a[0];
        for (c = 0; c * 2 + 1 < i; c = r) {
            r = c * 2 + 1;
            if (r+1 < i && a[r] < a[r+1]) ++r;
            if (t >= a[r]) break;
            a[c] = a[r];
        }
        a[c] = t;
    }
}

2012-07-26 00:03
long0042
Rank: 2
等 级:论坛游民
帖 子:38
专家分:50
注 册:2008-3-5
收藏
得分:0 
前面标号为1,2,3,4,5分别为选择排序,快速排序,快速排序改进,我写的堆排序,pangding写的堆排序。

以下是随机数排序结果比较:
2       快速排序 using time: 0.062000
3       快速排序 using time: 0.078000
4       堆排序 using time: 0.140000
5       堆排序 using time: 0.078000
2       快速排序 using time: 0.063000
3       快速排序 using time: 0.079000
4       堆排序 using time: 0.139999
5       堆排序 using time: 0.078000
2       快速排序 using time: 0.063000
3       快速排序 using time: 0.078001
4       堆排序 using time: 0.141001
5       堆排序 using time: 0.077999
2       快速排序 using time: 0.062000
3       快速排序 using time: 0.078001
4       堆排序 using time: 0.139999
5       堆排序 using time: 0.093000
2       快速排序 using time: 0.062000
3       快速排序 using time: 0.078001
4       堆排序 using time: 0.141001
5       堆排序 using time: 0.077999
2       快速排序 using time: 0.063000
3       快速排序 using time: 0.078003
4       堆排序 using time: 0.141003
5       堆排序 using time: 0.077999

以下是对顺序数据进行排序结果比较:
3       快速排序 using time: 0.031000
4       堆排序 using time: 0.125000
5       堆排序 using time: 0.062000
3       快速排序 using time: 0.031000
4       堆排序 using time: 0.110000
5       堆排序 using time: 0.062000
3       快速排序 using time: 0.030999
4       堆排序 using time: 0.125000
5       堆排序 using time: 0.062000
3       快速排序 using time: 0.031000
4       堆排序 using time: 0.125000
5       堆排序 using time: 0.063000
3       快速排序 using time: 0.032000
4       堆排序 using time: 0.125000
5       堆排序 using time: 0.062000
3       快速排序 using time: 0.032000
4       堆排序 using time: 0.125000
5       堆排序 using time: 0.062000
3       快速排序 using time: 0.032001
4       堆排序 using time: 0.125000
5       堆排序 using time: 0.063000
3       快速排序 using time: 0.031998
4       堆排序 using time: 0.125000
5       堆排序 using time: 0.063000

嗯。 总的来说快速排序效果还是最好的,不过你写的堆排序从效率上讲比我的要好那么一些。
我可以顺便学习下你写的这个了。
2012-07-26 09:32
快速回复:几种排序算法效率比较
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.019706 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved