帶頭結點的連結串列及選單 2018年12月26日
阿新 • • 發佈:2019-01-01
帶頭結點的連結串列及選單 2018年12月26日
以下內容僅供娛樂,歡迎隨時探討,請多指教!
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
/*定義結構體*/
struct student {
int num;
float score;
struct student *next;
};
/*初始化連結串列*/
struct student *Init_List() {
struct student *head;
head=(struct student*)malloc(sizeof (struct student) );
if(head==NULL) { //小心別漏這個
printf("申請頭結點失敗!\n");
return NULL;
}
head->next=NULL;
return head;
}
/*建立帶頭結點的連結串列*/
struct student *create_head(struct student *head) {
int sno;
float score;
struct student *p,*q;
q=head;
while(q->next) q=q->next;
printf("請輸入學號和成績,學號輸入-1結束: " );
scanf("%d%f",&sno,&score);
while(sno>=0) {
p=(student *)malloc(sizeof(student));
p->num=sno;
p->score=score;
q->next=p;
q=p;
scanf("%d%f",&sno,&score);
}
q->next=NULL;
return head;
}
/*將s指向的結點插入連結串列,使連結串列保持升序,並返回頭結點*/
void insert(struct student *head,struct student *s) {
struct student *p=head;
while(p->next!=NULL&&s->score>p->next->score)//特別注意&&左右不能寫反,若s最大,最後p->next=NULL,p->next->score執行出錯
p=p->next;
if(p->next==NULL) { //s->score最大的情況 //其實兩種情況可以並在一塊寫
p->next=s; //連線結點
s->next=NULL; //p->next就等於NULL
} else {
s->next=p->next;
p->next=s; //連線結點,這兩條語句不要寫反
}
}
/*查詢符合條件的結點,並返回指向該結點的指標*/
struct student * search(struct student *head,int num) {
struct student *p=head->next;
while(p!=NULL&&p->num!=num) //特別注意兩條件不能寫反,若寫反最後p指向NULL時p->num找不到 執行出錯
p=p->next;
return p;
}
/*輸出連結串列各結點的值,也稱對連結串列的遍歷*/
void print(struct student *head) {
struct student *p;
printf(" 連結串列如下: \n");
p=head->next;
while(p) {
printf("%d\t%.1f\n",p->num,p->score);
p=p->next;
}
}
/*釋放連結串列*/
void free_list(struct student *head) {
struct student *p=head ;
printf("釋放連結串列:\n");
while(p!=NULL) {
head=head->next;
free(p);
p=head;
}
printf("釋放連結串列成功!\n");
}
/*刪除連結串列中值為num的結點,並返回連結串列的首指標*/
void delete_note(struct student *head,int num_x) {
struct student *p1=head->next , *p2=head ;
while(p1!=NULL&&p1->num!=num_x) { //特別注意&&左右條件不能調換,若調換如果p1指向NULL時p1->num執行出錯
p2=p1;
p1=p1->next;
}
if(p1==NULL) return;
p2->next=p1->next;
free(p1);
}
//獲取連結串列長度(不包括頭節點)
int Size_List(struct student* head) {
struct student* temp = head->next;
int size = 0;
while (temp) {
size++;
temp = temp->next;
}
return size;
}
//連結串列的排序(冒泡)
void Sort_List(struct student* head) {
int i,j, n = Size_List(head);
struct student *p;
int t;
float r;
for (i=1; i<n; i++) {
p=head->next;
for (j=1; j<=n-i; j++) {
if (p->score > p->next->score) {
t=p->num,p->num=p->next->num,p->next->num=t;
r=p->score,p->score=p->next->score,p->next->score=r;
}
p=p->next;
}
}
}
/*完整的有頭結點連結串列操作程式*/
int main() {
struct student *p , *head ;
char c;
int num ;
float score ;
printf("有頭結點連結串列操作程式:\n");
head=Init_List();
while(1) {
printf("\nC:建立連結串列 I:插入結點(自動升序) P:輸出連結串列 "
" S:查詢結點 D:刪除結點 X:排序 E:釋放連結串列並退出程式! \n ");
c=getch();
switch(c) {
case 'I':
case 'i':
printf("請分別輸入要插入學生的學號和分數:\n");
scanf("%d%f",&num,&score);
p=(struct student*)malloc( sizeof(struct student) );
if(p==NULL) {
printf("申請該結點失敗!!!\n");
exit (0) ;
}
p->num=num;
p->score=score; //給p賦值
insert(head,p);
printf("插入成功!\n");
break;
case 'C':
case 'c':
head=create_head(head);
break;
case'P':
case 'p':
print(head);
break;
case'S':
case 's':
printf("輸入要查詢的學號\n");
scanf("%d",&num);
p=search(head,num);
if (p) {
printf("該學生資訊為: ");
printf("num=%d,score=%f\n",p->num,p->score);
} else
printf("該學生不存在\n");
break;
case'D':
case 'd':
printf("請輸入要刪除的學生的學號:\n");
scanf("%d",&num);
delete_note(head,num);
break;
case 'X':
case 'x':
Sort_List(head);
break;
case 'E':
case 'e':
free_list(head);
exit (0);
}
}
return 0;
}