鏈表是一種常見的基礎數據結構,結構體指針在這里得到了充分的利用。
鏈表可以動態的進行存儲分配,也就是說,鏈表是一個功能極為強大的數組,他可以在節點中定義多種數據類型,還可以根據需要隨意增添,刪除,插入節點。
鏈表都有一個頭指針,一般以head來表示,存放的是一個地址。鏈表中的節點分為兩類,頭結點和一般節點,頭結點是沒有數據域的。鏈表中每個節點都分為兩部分,一個數據域,一個是指針域。
說到這里你應該就明白了,鏈表就如同車鏈子一樣,head指向第一個元素:第一個元素又指向第二個元素;……,直到最后一個元素,該元素不再指向其它元素,它稱為“表尾”,它的地址部分放一個“NULL”(表示“空地址”),鏈表到此結束。
作為有強大功能的鏈表,對他的操作當然有許多,比如:鏈表的創建,修改,刪除,插入,輸出,排序,反序,清空鏈表的元素,求鏈表的長度等等。
創建鏈表:
typedef struct student{ int score; struct student *next; } LinkList;(注意分號)
一般創建鏈表我們都用typedef struct,因為這樣定義結構體變量時,我們就可以直接可以用LinkList *a;定義結構體類型變量了。
知識拓展:
typedef是C語言的關鍵字,作用是為一種數據類型定義一個新名字。這里的數據類型包括內部數據類型(int,char等)和自定義數據類型(struct等)。
在編程中使用typedef的目的一般有兩個,一個是給變量一個易記且意義明確的新名字,另一個是簡化一些比較復雜的類型聲明。
第一種 :
typedef struct student{
int score; struct student *next; } LinkList;
該語句實際上完成了兩個操作:
(1)定義一個新的結構類型:
typedef struct student{
int score; struct student *next; } ;
(2)typedef為這個新的結構起了一個名字,叫做LinkList。
初始化一個鏈表,n為鏈表節點個數:
LinkList *creat(int n){ LinkList *head, *node, *end;//定義頭節點,普通節點,尾部節點; head = (LinkList*)malloc(sizeof(LinkList));//分配地址 end = head; //若是空鏈表則頭尾節點一樣 for (int i = 0; i < n; i++) { node = (LinkList*)malloc(sizeof(LinkList)); scanf("%d", &node->score); end->next = node; end = node; } end->next = NULL;//結束創建 return head; }
修改鏈表節點值:
修改鏈表節點值很簡單。下面是一個傳入鏈表和要修改的節點,來修改值的函數。
void change(LinkList *list,int n) {//n為第n個節點 LinkList *t = list; int i = 0; while (i < n && t != NULL) { t = t->next; i++; } if (t != NULL) { puts("輸入要修改的值"); scanf("%d", &t->score); } else { puts("節點不存在"); } }
刪除鏈表節點:
刪除鏈表的元素也就是把前節點的指針域越過要刪除的節點指向下下個節點。即:p->next = q->next;然后放出q節點的空間,即free(q)。
void delet(LinkList *list, int n) { LinkList *t = list, *in; int i = 0; while (i < n && t != NULL) { in = t; t = t->next; i++; } if (t != NULL) { in->next = t->next; free(t); } else { puts("節點不存在"); } }
插入鏈表節點:
插入節點就是用插入前節點的指針域鏈接上插入節點的數據域,再把插入節點的指針域鏈接上插入后節點的數據域。根據圖,插入節點也就是:e->next = head->next; head->next = e。
增加鏈表節點用到了兩個結構體指針和一個int數據。
void insert(LinkList *list, int n) { LinkList *t = list, *in; int i = 0; while (i < n && t != NULL) { t = t->next; i++; } if (t != NULL) { in = (LinkList*)malloc(sizeof(LinkList)); puts("輸入要插入的值"); scanf("%d", &in->score); in->next = t->next;//填充in節點的指針域,也就是說把in的指針域指向t的下一個節點 t->next = in;//填充t節點的指針域,把t的指針域重新指向in } else { puts("節點不存在"); } }
輸出鏈表:
輸出鏈表很簡單,邊遍歷邊輸出就行了。
while (h->next != NULL) { h = h->next; printf("%d ", h->score); }