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

时间:2021-09-01 13:16:47

本文实例为大家分享了C语言链表实现歌手评分系统的具体代码,供大家参考,具体内容如下

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#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;//指针后移
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_42680202/article/details/81043280