1、單向鏈表的定義
struct student { char name[10]; float score; struct student *next; };
next作為同類型指針,指向與它所在節點一樣的節點。
2、單向鏈表的基本操作
1)建立鏈表
int main() { /*定義結構指針,pnew指向新節點,head指向頭節點,tail指向尾節點*/ struct student *pnew, *head, * ptail; /* 動態分配庫函數malloc,分配長度為sizeof(struct student)的存儲空間,函數返回分配到空間的起始地址, 指向的類型為強制類型轉換后的struct student*. malloc的頭文件stdlib.h */ pnew = (struct student*) malloc(sizeof(struct student)); /* 空鏈表中建立頭節點操作。 */ scanf("%s%f",pnew->name,&pnew->score); head = pnew; ptail = pnew; /* 向現有鏈表中添加新節點。 */ pnew = (struct student*) malloc(sizeof(struct student)); scanf("%s%f",pnew->name,&pnew->score); ptail->next = pnew; ptail = pnew; /* 將末節點指向下一節點的成員賦值為NULL */ ptail->next = NULL; }
/*定義創建函數create,建立一個有n個節點的單向鏈表*/ struct student *create(int n) { struct student *pnew, *head, *ptail; int i; pnew = (struct student*) malloc(sizeof(struct student)); scanf("%s%f",pnew->name, &pnew->score); head = ptail = pnew; for (i = 1; i < n; i++) { pnew = (struct student*) malloc(sizeof(struct student)); scanf("%s%f",pnew->name, &pnew->score); ptail->next = pnew; ptail = pnew; } ptail->next = NULL; return head; }
2)遍歷鏈表
/*定義輸出鏈表節點信息函數print,形參head為鏈表頭指針*/ void print(struct student *head) { struct student *p = head; while (p != NULL) { printf("%s %.1f\n",p->name, p->score); p = p->next; } }
3)在鏈表中插入節點
/*定義函數insert,在有序鏈表中插入一個節點,使鏈表按score成員從大到小排列節點*/ struct student* insert(struct student *head) { struct student *p = head, *pnew, *pold = head; pnew = (struct student*) malloc(sizeof(struct student)); scanf("%s%f",pnew->name,&pnew->score); if (pnew->score > head->score) //當新結點score值大於頭結點時,將新結點指向頭節點,再作為頭節點 { pnew->next = head; head = pnew; } else { while(p != NULL && pnew->score < p->score) { pold = p; p = p->next; } pold->next = pnew; pnew->next = p; } return head; }
4)在鏈表中刪除節點
/*定義函數pdelete,在鏈表中刪除所有成員score值大於等於grade值的節點。*/ struct student *pdelete(struct student *head, int grade) { struct student *p,*pold; p = head; while (head != NULL && head->score >= grade) //當頭結點為所刪除節點時,將頭結點指向下一節點,並釋放其空間。 { head = head->next; free(p); p = head; } if (head == NULL) return head; p = head->next; pold = head; //pold指向剛才已檢查過的結點。 while (p != NULL) { if(p->score >= grade) { pold->next = p->next; free(p); p = pold->next; } else { pold = p; p = p->next; } } return head; }
題目1
/*輸入n個學生的信息(姓名,成績),根據成績數據建立一個鏈表,使鏈表中的節點按成績從高到低連接起來。*/ #include <stdio.h> #include <stdlib.h> struct student { char name[10]; float score; struct student *next; }; struct student* insert(struct student *); void print(struct student *); int main() { struct student *head; int i, n; scanf("%d",&n); head = (struct student*) malloc(sizeof(struct student)); scanf("%s%f",head->name, &head->score); head->next = NULL; for (i = 1;i < n; i++) { head = insert(head); } print(head); return 0; }
題目2
/*輸入n個學生的信息(姓名、成績),輸出所有學生的節點信息,刪除鏈表中所有不參加補考同學的節點,最后再輸出要補考學生的節點信息*/ #include <stdio.h> #include <stdlib.h> struct student { char name[10]; float score; struct student *next; }; struct student* insert(struct student *); void print(struct student *); struct student *create(int ); struct student *pdelete(struct student *, int ); int main() { struct student *head; int n; scanf("%d",&n); head = create(n); print(head); head = pdelete(head,60); print(head); return 0; }
單鏈表冒泡排序
修改數據,或者 先全部修改,再還原指針(這里用第二種方法)
pi = head; while (pi->next != NULL) { pj = pi->next; while (pj != NULL) { if (pi->date > pj->date) { t = *pi; *pi = *pj; *pj = t; t.next = pi->next; pi->next = pj->next; pj->next = t.next; } pj = pj->next; } pi = pi->next; }