求用c语言怎么对结构体进行排序

alee777 2006-12-12 04:05:30
各位大哥,帮个忙,我要写个程序,要用c语言对结构体进行排序。结构体里有学生姓名,数学成绩,英语成绩,语文成绩。
对三个关键字进行排序,按数学成绩-〉英语成绩-〉语文成绩排,结构体间不交换数据,而是改变指针。(学生人数比较多)
各位高手能给我一个代码吗?谢谢
...全文
1892 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
Softwaring 2010-06-06
  • 打赏
  • 举报
回复
学习中……
东莞某某某 2010-06-06
  • 打赏
  • 举报
回复
typedef   struct   Node{ 
int data;
struct Node *next;
}* List , Node;



void sort(List *list) /* Selection Sort */
{
Node *h, *t, *s, *tail, *u, *v;
h = (*list);
s = NULL;
while(h){
for(t=u=h; !u->next; u=u->next)
if(u->next->data < t->data)
{
v = u;
t = u->next;
}

if(t==h)
{
h = h-> next;
}
else
{
v->next = t->next;
}

if(!s)
{
tail=s=t;
}
else
{
tail = tail->next = t;
}
}

if(s) tail->next = NULL;

*list=s;
}


自己改下
bobo_guan 2010-06-06
  • 打赏
  • 举报
回复
写个链表排序
把比较的部分替换成自定义的比较函数就行了
比较函数可以根据需要的逻辑写
softwarewander 2006-12-14
  • 打赏
  • 举报
回复
呵呵, 瞌睡虫的代码好像也进行了 结构体的交换哈
短歌如风 2006-12-14
  • 打赏
  • 举报
回复
要做到“结构体间不交换数据,而是改变指针”,必须你的数据结构支持。

可以选择“结构指针数组”而不用“结构数组”,然后用那几种常见的排序算法就行了,推荐“快速排序”,简单实用。

也可以选择链表,然后可以用“选择排序”、“插入排序”、“冒泡排序”、“归并排序”。推荐“归并排序”可以实现时间O(N*log(N)),如果是双向链表还可以空间O(1)。
softwarewander 2006-12-14
  • 打赏
  • 举报
回复
我的代码就是按你说的意思写的。

但是好像输出 学号的时候是乱码。 其他的还好。还有就是我在结构体中多加了一个标志
我把所有代码给你,直接可以运行的。你看看吧

#define MAX 35

typedef struct tagSTU
{
char id[5];
float scores[3];
float avg;
float tot;
unsigned int sorted; //1表示已被排过序,0表示没有
}STU;
int num;

STU* createSTU()
{
STU *stu=(STU*)malloc(sizeof(STU));
printf("请输入ID及成绩(以空格分开)\n");
scanf("%s%f%f%f",stu->id,&stu->scores[0],&stu->scores[1],\
&stu->scores[2]);
stu->tot=stu->scores[0]+stu->scores[1]+stu->scores[2];
stu->avg=stu->tot/3;
stu->sorted=0; //创建的时候都没有被排序
return stu;
}

//参数baseadd是结构体数组的首地址,
//并且先按照scores[0]排序, 如果项等按照scores[1],如果还想等则按照scores[2]排序
STU * locate(STU * baseadd) //本函数返回未被排序的结构体中,最大的一个结构体的指针
{
STU *cur=baseadd; //cur 的不可重入性导致的 id字段是垃圾字符
STU * biger=(STU *)malloc(sizeof(STU));
strcpy(biger->id,"*"); //随便写了一个字符 不过应当尽量小至少比数字小
biger->scores[0]=0;
biger->scores[1]=0;
biger->scores[2]=0;
biger->avg=0;
biger->tot=0;
biger->sorted=0;
int scope=1;//=baseadd+(num*sizeof(STU)-cur;
while(scope>0)
{
if(cur->sorted!=1)
{
if(cur->scores[0]>biger->scores[0]) //比较第一列 将大的附值给biger
{
biger=cur;
}
else
{
if(cur->scores[0]==biger->scores[0]) //如果第一例相等
{
if(cur->scores[1]>biger->scores[1]) //将第二列大的附值给biger
biger=cur;
else
{
if(cur->scores[1]==biger->scores[1]) // 如果第2列也相等
{
if(cur->scores[2]>biger->scores[2]) //将第三列大的附值给biger
biger=cur;
}
}
}
}
}

cur++;
scope=(int)((baseadd+num)-cur);
}
return biger;

}

STU * isort(STU *baseadd)
{
STU * head_sorted;
STU * p=baseadd;
void ** plink;
plink=(void **)baseadd;
int i=num;
static int isfirst=0;
while(i>0)
{
p=locate(baseadd);
if(isfirst==0)
{
head_sorted=p; //保留排完序之后的第一个机构体的指针, 用于返回
isfirst++;
}
*plink=(void *)p;//将p转化成void的时候,为什么head_sorted和 H 中的id字段会变成垃圾字符?而其他的不会呢
p->sorted=1;
plink=(void **)p;
i--;
}
*plink=(void *)0;
return head_sorted;
}

void printit(STU *baseadd)
{
STU *p=baseadd;
void *cur=baseadd;
while(*(void **)cur)
{
p=(STU *)cur;
printf("%s->%f->",p->id,p->scores[0]);
cur=*(void **)cur;
}
}

int main()
{
int i=0,s=0;
STU stu[MAX];
printf("请输入人数(<35)\n");
scanf("%d",&num);
if(num<1||num>MAX)return -1;
while(i<num)
{
stu[i]=*createSTU();
fflush(stdin); //吃掉缓冲区内的字符
i++;
}
STU * THE;
THE=isort(stu);
printit(THE);
system("pause");
return 0;
}




alee777 2006-12-14
  • 打赏
  • 举报
回复
谢谢各位热心的帮忙。我程序要的就是下面引用Bennyatt的这个意思,要写程序的。
而且结构体间数据不交换,而是改变指针。

你说的是这个意思吧?
如果有 数学成绩 相等的人
他们之间 按照 英语成绩排
如果他们之间再有相等的就 按照 语文成绩排?
jixingzhong 2006-12-12
  • 打赏
  • 举报
回复
本程序根据 总成绩 排序,
把排序关键字段 修改为你要求的字段就可以了


(1)由键盘输入每个学生的学号和四门课程的成绩
(2)计算每个学生的平均成绩和总成绩
(3)按总成绩从高到低排名,并按名次输出每个学生的情况,包括:学号,各科成绩,平均成绩,总成绩,排名
(4)根据要求输出某门课程(由键盘输入课程号)成绩在90分(含90分)以上且总分在前5名的学生情况

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 35
typedef struct tagSTU
{
char id[28];
float scores[4];
float avg;
float tot;
}STU;
STU* createSTU()
{
STU *stu=(STU*)malloc(sizeof(STU));
printf("请输入ID及成绩(以空格分开)\n");
scanf("%s%f%f%f%f",stu->id,&stu->scores[0],&stu->scores[1],\
&stu->scores[2],&stu->scores[3]);
stu->tot=stu->scores[0]+stu->scores[1]+stu->scores[2]+stu->scores[3];
stu->avg=stu->tot/4;
return stu;
}
void Equal(STU *a,STU *b)
{
a->scores[0]=b->scores[0];
a->scores[1]=b->scores[1];
a->scores[2]=b->scores[2];
a->scores[3]=b->scores[3];
strcpy(a->id,b->id);
a->avg=b->avg;
a->tot=b->tot;
}
void Sort(STU *addr,int num)
{
int i,j;
STU temp;
for(i=num-1;i>0;i--)
{
for(j=0;j<i;j++)
{
if(addr[j].tot<addr[j+1].tot)
{
Equal(&temp,&addr[j]);
Equal(&addr[j],&addr[j+1]);
Equal(&addr[j+1],&temp);
}
}
}
}

void Show(STU *addr,int num)
{
int i=0;
while(i<num)
{
printf("id:%s\n%.2f %.2f %.2f %.2f %.2f %.2f\n",addr[i].id,addr[i].scores[0],\
addr[i].scores[1],addr[i].scores[2],addr[i].scores[3],addr[i].avg,addr[i].tot);
i++;
}
}

void Showsub(STU *addr,int num,int s)
{
int i=0;
while(i<num&&i<5)
{
if(addr[i].scores[s]>89)
printf("id:%s\n%.2f %.2f %.2f %.2f %.2f %.2f\n",addr[i].id,addr[i].scores[0],\
addr[i].scores[1],addr[i].scores[2],addr[i].scores[3],addr[i].avg,addr[i].tot);
i++;
}
}
int main()
{
int num,i=0,s=0;
STU stu[MAX];
printf("请输入人数(<35)\n");
scanf("%d",&num);
if(num<1||num>MAX)return -1;
while(i<num)
{
stu[i]=*createSTU();
i++;
}
Sort(stu,num);
Show(stu,num);
printf("输入课号(0-3)\n");
scanf("%d",&s);
if(s<0||s>3)return -1;
Showsub(stu,num,s);
system("PAUSE");
return 0;
}
Bennyatt 2006-12-12
  • 打赏
  • 举报
回复
你说的是这个意思吧?
如果有 数学成绩 相等的人
他们之间 按照 英语成绩排
如果他们之间再有相等的就 按照 语文成绩排?
嘿嘿。。。。
要下班了,明天会很忙了,
如果是不是非要编程那我可以帮你处理数据,要是编程那就没时间了。。
Bennyatt 2006-12-12
  • 打赏
  • 举报
回复
你是要 解决实际问题?
还是要 做这个算法???
如果是解决这个问题那么不需要编程。可以用数据库软件 甚至 exl就可以做
如果要编程那就得写代码了
Integrate01 2006-12-12
  • 打赏
  • 举报
回复
基数排序

69,381

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧