C语言链表实现歌手评分系统

此程序可以添加文件操作用于保存歌手得分等信息,此程序实现了链表的增删查和链表冒泡排序交换节点功能



#include <stdio.h>
#include  <stdlib.h>
#include <string.h>
//创建结构体及其成员 
typedef struct Node
{
	int num;//编号 
	char name[20];//姓名 
	float grade[10];//评委评分 
	float sum;//总分 
	float ave;//平均分 
	struct Node *next;//指针域 
}S;//结构体定义为S
//各函数定义
void menu(); //菜单函数 
S *create();//创建链表函数 
void print(S *);//输出链表函数 
void insert(S *);//插入节点函数 
void del(S *);//删除节点函数 
void search(S *);//查找节点函数 
void sort(S *);//节点排序函数 
void cal(S *);//计算选手数据函数  
//主函数 
int main()
{
	S *head;
	int n,a=1;//n用来控制选择操作类型,a控制循环,以-1终止 
	while(a>0)
	{
		menu();//显示菜单 
		printf("you want to do:");	
		scanf("%d",&n);//选择操作 
		switch(n)//各操作数字对应菜单数字,通过n确定操作类型 
		{
			case 1://创建 
				head=create();
				print(head);
				break;
			case 2://计算 
			     cal(head);
			     print(head);
			     break;
			case 3://插入 
				insert(head);
				print(head);
				break;
			case 4://删除 
				del(head);
				print(head);
				break;
			case 5://查找 
				search(head);
				break;
			case 6://排序 
			    sort(head);
				print(head);
				break;
			case 7://保存 
				save(head);
				break;
			case 8:
				read();//读取 
				print(head);
				break;
			default:
				a=-1;//跳出循环条件 
				break;
		}	
	}
	return 0;
}

//菜单模块直接显示 
void menu()
{
	printf("\n\n");
	printf("\t\t|----------SCORE-----------|\n");
	printf("\t\t|\t1.create           |\n");
	printf("\t\t|\t2.cal              |\n");
	printf("\t\t|\t3.insert           |\n");
	printf("\t\t|\t4.del              |\n");
	printf("\t\t|\t5.search           |\n");
	printf("\t\t|\t6.sort             |\n");
	printf("\t\t|\t9.exit program     |\n");
	printf("\t\t|--------------------------|\n");
	printf("\t\t\tchoice(1-9):\n");
}

//创建链表模块 
S *create()
{
	S *head,*p,*q;//定义指针 
	int i;
	head=(S *)malloc(sizeof(S));//头节点开辟空间
	head->ave=NULL;//置空头节点的ave成员 
	head->next=NULL;//置空头节点的指针域 
	q=head;//q指针记录头节点的地址 
	p=head->next;//p指针记录头节点的指针域的地址 
	printf("please input singer's num and name\n");
	int num;
	scanf("%d",&num);
	while(num!=0)//输入选手编号输入为零停止循环 
	{
		p=(S *)malloc(sizeof(S));//p指针开辟空间
		//输入各成员 
		p->num=num;
		scanf("%s",p->name);
		printf("please input singer's score:\n");
		for(i=0;i<10;i++)
		{
		scanf("%f",&p->grade[i]);
	    } 
	    p->sum=0;
	    p->ave=0;
		p->next=NULL;//置空p节点的指针域  
		q->next=p;//p,q节点连接 
		q=p;//q指针后移 
		scanf("%d",&num);
	}
	return head;//返回链表的起始地址 
}

//计算模块 
void cal(S *head)
{
	S *p;//定义p指针 
	int i;
	float max,min;//记录最高分最低分 
	p=head->next;//p记录头节点的指针域地址 
	while(p)//p不为空时进行计算 
	{
	p->sum=0;//每次计算初始化sum 
	min=max=p->grade[0];//每次计算初始化min,max 
	for(i=0;i<10;i++)
	{
		p->sum+=p->grade[i];//计算总分 
		if(p->grade[i]>max)
		max=p->grade[i];//记录最高分 
		if(p->grade[i]<min)
		min=p->grade[i];//记录最低分 
	}
	p->ave=(p->sum-max-min)/8;//计算平均(去掉最高分最低分) 
	p=p->next;//p指针后移 
   }	
}

//插入节点模块(可多个插入) 
void insert(S *head)
{
	int i,num,flag=1;//flag实现判断指针是否到达最后一个节点 
	float min,max;//min,max记录最高分最低分 
	S *p,*q,*r;	//定义指针便于插入操作 
	printf("please input a singer's messages:\n");
	printf("please input singer's num:\n");
	scanf("%d",&num);
	while(num!=0)//输入编号不为零时循环,以零终止,可实现多个插入 
	{
	r=(S *)malloc(sizeof(S));//为r开辟空间 
	r->next=NULL;//置空r的指针域 
	//输入相关数据,并计算相关数据 
	r->num=num; 
	printf("please input singer's name:\n");
	scanf("%s",r->name);
	printf("please input singer's score:\n");
	r->sum=0;
	for(i=0;i<10;i++)
	{
	scanf("%f",&r->grade[i]);
	r->sum+=r->grade[i];
    }  
    min=max=r->grade[0];
    for(i=0;i<10;i++)
    {
        if(r->grade[i]>max)
		max=r->grade[i];
		if(r->grade[i]<min)
		min=r->grade[i];	
	}
	r->ave=(r->sum-max-min)/8;
	q=head;//q指针记录头节点的地址 
	p=head->next;//p指针记录头节点的指针域的地址 
	while(q->next!=NULL&&p->ave<r->ave)//循环条件:当q->next不为空,以及p->ave<r->ave实现插入后无需排序 
	{
		p=p->next;//p指针后移 
		q=q->next;//q指针后移
		if(q->next==NULL)//这个判断防止q->next为空时,在执行循环是出现野指针使程序出错 
	    {
		    p=NULL;//防止出现野指针p 
		    q->next=r;//连接节点 
		    r->next=NULL;//置空r指针域 
		    flag=0;//到达最后一个节点更改flag 
		    break;
	    }
	}
	if(flag)//判断是否到达最后一个节点,为真执行该操作 
	{
		r->next=p;
		q->next=r;
		//实现将r节点插入链表 
	}
	printf("please input singer's num:\n");
        scanf("%d",&num);
	}
}

//删除节点模块 
void del(S *head)
{
	S *p,*q;//定义指针 
	int b;//用于输入编号查找删除 
	p=head;//p记录头节点的地址 
	q=head->next;//q记录头节点的指针域的地址 
	printf("input singer's num you want to delete:");
	//输入编号 
	scanf("%d",&b);
	while(q!=NULL)//q不为空时执行循环 
	{
		if(q->num==b)//判断是否找到输入的编号 
		//为真时 
		{
			p->next=q->next;//断开q节点 
			free(q);//释放q节点neicun 
			q=NULL;	//置空q指针防止出现野指针 
		}
		else
		{
			//判断为假时 
			p=p->next;//p指针后移 
			q=q->next;//q指针后移 
		}
	}	
	if(p==NULL)//当查找到最后一个节点还未查到要删除的编号时,输出ERROR INPUT
	printf("ERROR INPUT\n");
}

//查找节点模块 
void search(S *head)
{
	S *p;//定义指针 
	int b;//定义b用于输入查找编号 
	printf("input the singer's num you are searching:");
	//输入查找编号 
	scanf("%d",&b);
	p=head->next;
	while(p!=NULL)
	{
		if(p->num==b)//判断是否找到选手编号 
		{
			//为真时,输出信息 
			printf("%d %s %.2f %.2f\n",p->num,p->name,p->sum,p->ave);
			break;
		}
		else
		//为假时 
		p=p->next;//指针后移 
	}
	if(p==NULL)//查找到最后一个节点还未查到要的编号时,输出ERROR INPUT
		printf("ERROR INPUT\n");
}

//排序节点模块
//采用冒泡排序,交换节点 
void sort(S *head)  
{                        
  S *p,*pre,*temp,*tail;

tail = NULL;

// 算法的核心部分,节点交换 
while( head->next != tail ){
     pre= head;
     p = head->next;
   while( p->next != tail ){
         if( p->ave > p->next->ave ){
              temp = p->next;
              pre->next = p->next;
                p->next = p->next->next;
                pre->next->next = p;
                p = temp;
            }
            // 节点后移
            p = p->next;
            pre= pre->next;
        }
        tail = p;
    }
}
 
//输出链表模块 
void print(S *head)
{
	int i;
	S *p=head->next;
	while(p)//当p不为空的时候执行 
	{
		printf("%d %s %.2f %.2f\n",p->num,p->name,p->sum,p->ave);
		for(i=0;i<10;i++)
		printf("%.2f ",p->grade[i]);
		printf("\n");
		p=p->next;//指针后移 
	}
}



  • 5
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值