链表与排序的结合

//	为足球队员建立记录,要有姓名、所属俱乐部、身高、年龄、按身高降序排列输出,再按年龄降序排列输出
#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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值