// 为足球队员建立记录,要有姓名、所属俱乐部、身高、年龄、按身高降序排列输出,再按年龄降序排列输出
#include<stdio.h>
#include<stdlib.h>
#define LEN sizeof(struct player)
typedef struct player
{
char name[10];
char club[10];
float height;
int age;
struct player *next; //可以在做一个指针域保存上一个节点的地址 ,这种方法在后面很方便
}Player;
Player *creat(int n)
{
Player *p,*prep,*head;
int i=0;
for(i=0;i<n;i++)
{
if(i==0)
{
if ((head=p=prep=(Player *)malloc(LEN)) == NULL)
{
printf("Failure to apply for space");
exit(0);
}
}
else
{
if((p=(Player*)malloc(LEN)) == NULL)
{
printf("Failure to apply for space");
exit (0);
}
prep->next = p;
prep = p;
}
}
p->next = NULL;
return (head);
}
void assign(Player *head)
{
Player *p;
char *a,b;
a=&b;
FILE *fp;
int i=0;
if ((fp=fopen("text","w+")) == NULL)
{
printf("The file text was not open");
exit(-1);
}
else
{
fprintf(fp,"汤海洋,俱乐1部,175,19,\
刘雨施,俱乐5部,174,18,\
唐学成,俱乐1部,179,19,\
潘鑫欣,俱乐3部,179,18,\
王璞,俱乐4部,172,17,\
谭啸,俱乐2部,170,18,");
fseek(fp,0l,SEEK_SET);
for(p=head;p;p=p->next)
{
fscanf(fp,"%[^,]%c%[^,]%c%f%c%d%c",p->name,a,p->club,a,&(p->height),a,&(p->age),a);
}
}
}
void show(Player *head)
{
while(head)
{
printf("name:%s club:%s heigh:%.0f age:%d\n",head->name,head->club,head->height,head->age);
head = head->next;
}
puts("");
}
Player *swaplink(Player *p1,Player *p2,int n=0)//p1是要交换的第一个节点的前驱,且p1在p2之前 ,当p1是头节点给n传非0值,否则可以不传;
{
Player *head,*p,*prep;
if(n)
{ //p1是头节点
head=p2->next;
p=p1->next;
p1->next=p2->next->next;
head->next=p;
p2->next=p1;
return head;
}
else //非头结点
{
if(p1->next==p2)
{
p=p2->next;
p1->next->next=p2->next->next;
p->next=p1->next;
p1->next=p;
}
else
{
p=p1->next->next;
p1->next->next=p2->next->next;
p2->next->next=p;
p=p2->next;
p2->next=p1->next;
p1->next=p;
}
}
}
Player * dechei(Player *head) //至少3个节点
{ //这个是把两个节点交换,涉及删除,插入,查找。
Player *p,*pi,*pj,*pmax;
for(pmax=pj=head;pj->next;pj=pj->next)
{
if(pmax->height<pj->next->height)
{
p=pj; //这个是pmax的值和pj的下一个节点的值比,所以pmax要存pj->next
pmax=pj->next; //这个查找和下面6排的查找和findmax是我想的三种思想
}
}
if(head!=p)
head=swaplink(head,p,1);
for (pi=head;pi->next->next;pi=pi->next)
{ //如果用多次交换,pj也会跟着交换,会跳过一些节点或重复一些节点,所以只交换一次。
for(pmax=pi,pj=pi->next;pj->next;pj=pj->next)
{
if(pmax->next->height<pj->next->height)
{
pmax=pj;
}
}
if(pi!=pmax)
swaplink(pi,pmax);
}
return head;
}
Player *findmax(Player *head)
{
if(!head->next)
return NULL;
Player *p,*maxp,*prep;
for(maxp=head,p=prep=head->next;p!=NULL;p=p->next) //只能先和自己比,然后prep就在p之前
{
if(maxp->next->age<p->age)
{
maxp=prep;
}
prep=p;
}
return maxp;
}
Player * decage(Player *head) //思路:创建一个新链表,每次从原链表中删除最大节点并把这个节点放在新链表里
{
Player *p,*prep,newhead,first,*pa;
first.next=head;
for(pa=&newhead;prep=findmax(&first);pa=pa->next)
{
p=prep->next;
prep->next=prep->next->next;
pa->next=p;
}
return newhead.next;
}
/* 其他思路,注,来自汤海洋。1.在比较过后的交换中,我的是交换链表的节点,但还可以交换链表里的数据而不改变链表顺序
可以利用结构体整体赋值再处理指针域。 2.创建一个结构体指针数组,依次从链表里找最大节点存在数组里,最后按数组顺序
从新建立链表,也很方便*/
int main()
{
Player *head,*pa,*pb,*pc,*pd,*pe,*pf;
head = creat(6);
assign(head);
pa=head,pb=pa->next,pc=pb->next,pd=pc->next,pe=pd->next,pf=pe->next;
show(head);
head=dechei(head);
show(head);
head=decage(head);
show(head);
}
链表与排序的结合
最新推荐文章于 2022-03-27 12:01:18 发布