| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2619 人关注过本帖
标题:堆排序(多关键字)
只看楼主 加入收藏
犬虫门心
Rank: 8Rank: 8
来 自:西安
等 级:蝙蝠侠
帖 子:209
专家分:753
注 册:2011-1-25
收藏
得分:0 
楼主,你都已经知道错误了,为什么不一次性全部改完呢?
之前只所以张冠李戴,是因为你犯了如下的错误:
void sift(int startPos,int endPos,int score[],int number[])
{
    int k=startPos*2+1,temp1,temp2;
    temp1=score[startPos];
    temp2=number[startPos];
    while(k<endPos)
    {
        if(k+1<endPos&&score[k]<score[k+1])
            k++;
        else if(k+1<endPos&&score[k]==score[k+1]&&number[k]>number[k+1])
            k++;
        if(temp1<score[k])
        {
            score[startPos]=score[k];//问题在这里!
            //你只调整了分数的位置,但没有调整相对应的学号的位置
            //number[startPos] = number[k];
            startPos=k;
            k=startPos*2+1;
        }
        else if(score[k]==temp1&&number[k]>number[k+1])
        {
            score[startPos]=score[k];//It's the same!
            startPos=k;
            k=startPos*2+1;
        }
        else break;
    }
    score[startPos]=temp1;
    number[startPos]=temp2;
}
其实,你的程序包含着一个非常重大的错误,是思路上的缺陷。但感觉你现在只想把这个小东西先完成了再说。如果你想有更大的进步,我希望你能继续就这个程序重新编写,用结构体,像“点线面”说的那样。
C语言程序设计有很广阔的天空呢,继续努力!!!

当一名对得起学生学费的老师,一直是我的目标!我会更努力的!
2011-01-29 18:29
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
这个程序已经写好了,请问我这个程序有什么非常重大的错误?

欢迎来到我的博客:http://blog..cn/noisunyuhong
2011-01-29 18:51
sunyh1999
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:14
帖 子:1178
专家分:3032
注 册:2009-5-17
收藏
得分:0 
你的意思是我的这个程序有问题,还是堆排序有问题?

欢迎来到我的博客:http://blog..cn/noisunyuhong
2011-01-29 18:52
犬虫门心
Rank: 8Rank: 8
来 自:西安
等 级:蝙蝠侠
帖 子:209
专家分:753
注 册:2011-1-25
收藏
得分:0 
程序没问题,但是你这个程序的思路很难具有扩展性。
首先,如果现在要考察的不仅仅是一个人的成绩和总成绩,而是一系列与现实生活和工作相关的信息,如:
姓名、学号、性别、出生日期,再加上你所考虑的多门成绩和总成绩。
在这样的情况下,你的程序的“重大思路错误”就显露无余了。
第二,在现实工作中,排序的要求也比较复杂,可能是单排序,可能是多重排序,面对这样复杂的局面,能否有一种相对变化最小的模式来适应尽可能多的现实要求,用这样的模式作为编程的指导思路,就能使编程真正地上一个大台阶了。
这里的核心思想是:一切从用户出发,与人方便、与己方便。

当一名对得起学生学费的老师,一直是我的目标!我会更努力的!
2011-01-29 19:06
BlueGuy
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:29
帖 子:4476
专家分:4055
注 册:2009-4-18
收藏
得分:0 
楼主有一个误区,总是把 所有的数据都排序完,
我觉得没有这个必要, 用选择排序 或是 冒泡排序 选出前5个就行了。

我就是真命天子,顺我者生,逆我者死!
2011-01-29 19:14
犬虫门心
Rank: 8Rank: 8
来 自:西安
等 级:蝙蝠侠
帖 子:209
专家分:753
注 册:2011-1-25
收藏
得分:0 
马后炮的说法是正确的,这就是两个关键点。
第一、用结构体,而非数组,这可以使你的“交换”、“赋值”部分的语句大大减少。
第二、排序的关键是交换,而交换的条件是关键的关键,这部分用函数来实现,甚至可以用到函数指针,可以进一步使功能灵活!
if(k+1<endPos&&score[k]<score[k+1])k++;
else if(k+1<endPos&&score[k]==score[k+1]&&number[k]>number[k+1])k++;
if(temp1<score[k])
 {
    score[startPos]=score[k];
    number[startPos]=number[k];
    startPos=k;
    k=startPos*2+1;
    }
    else if(score[k]==temp1&&number[k]>number[k+1])
    {
    score[startPos]=score[k];
    number[startPos]=number[k];
    startPos=k;
}
以上的代码是够蛋疼的。先定义结构体:
typedef struct STI
{
    char Name[11];
    float Score1;
    ...
    float Sum;
}STI;

void sift(int startPos, int endPos, STI *sti)
{
...
    STI temp;
...
    if(k+1 < endPos && yourComp(sti[k], sti[k+1]))
        k++;
    if(yourComp(temp, sti[k]))
    {
        sti[startPos] = sti[k];
        startPos = k;
    }

程序中的yourComp()是比较函数,你自己定义,爱怎么排就怎么排,比如:
int yourComp(STI a, STI b)
{
    return strcmp(a.Name, b.Name) > 0 ||
            strcmp(a.Name, b.Name) == 0 && a.sum < b.sum;
//先按姓名升序,姓名相同则按总成绩降序
}
这是提示,自己再考虑考虑。

当一名对得起学生学费的老师,一直是我的目标!我会更努力的!
2011-01-29 19:26
快速回复:堆排序(多关键字)
数据加载中...
 
   



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

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