鏈表也是線性表的一種,與順序表不一樣的是,它在內存中不是連續存放的。在C語言中,鏈表是經過指針相關實現的。而單鏈表是鏈表的其中一種,關於單鏈表就是其節點中有數據域和只有一個指向下個節點的指針域。建立單鏈表的方法有兩種,分別是頭插法和尾插法。算法
所謂頭插法,就是按節點的逆序方法逐漸將結點插入到鏈表的頭部。反之尾插法就是按節點的順序逐漸將節點插入到鏈表的尾部。相對來講,頭插法要比尾插法算法簡單,可是最後產生的鏈表是逆序的,即第一個輸入的節點實際是鏈表的最後一個節點。而爲了習慣,一般用尾插法來建立鏈表。下面的代碼就是實現了頭插法和尾插法。代碼在Linux下調試經過。指針
#include <stdio.h> #include <stdlib.h> typedef struct link { char data; struct link *next; }linklist; linklist *CreateList_Front(); //頭插法建立單鏈表 linklist *CreateList_End(); //尾插法建立單鏈表 void ShowLinklist(linklist *h); //輸出顯示鏈表 int main(void) { int choice; linklist *head; //head = (linklist*)malloc(sizeof(linklist)); while(1) { printf("單鏈表的建立\n"); printf("1.使用頭插法建立單鏈表\n"); printf("2.使用尾插法建立單鏈表\n"); printf("3.鏈表輸出顯示\n"); printf("4.退出\n"); printf("作出選擇:\n"); scanf("%d",&choice); switch(choice) { //頭插法 case 1: head = CreateList_Front(); break; //尾插法 case 2: head = CreateList_End(); break; //輸出鏈表 case 3: ShowLinklist(head); break; //退出程序 case 4: return 0; break; default: break; } } return 1; } linklist *CreateList_Front() { linklist *head, *p; char ch; head = NULL; printf("依次輸入字符數據(‘#’表示輸入結束):\n"); ch = getchar(); while(ch != '#') { p = (linklist*)malloc(sizeof(linklist)); p->data = ch; p->next = head; head = p; ch = getchar(); //頭插法算法簡單 核心就兩句p->next = head;head = p; } return head; } linklist *CreateList_End() { linklist *head, *p, *e; char ch; head = NULL; e = NULL; printf("請依次輸入字符數據('#'表示輸入結束):\n"); ch = getchar(); while(ch != '#') { p = (linklist*)malloc(sizeof(linklist)); p->data = ch; if(head == NULL) //先判斷輸入的是否是第一個節點 { head = p; } else { e->next = p; //e始終指向輸入的最後一個節點 } e = p; ch = getchar(); } if(e != NULL) //若是鏈表不爲空,則最後節點的下一個節點爲空 { e->next = NULL; } return head; //尾插法比頭插法複雜一些,程序中要作兩次判斷,分別是判斷第一個節點和最後一個節點的判斷。且消耗多一個指針變量e。 } void ShowLinklist(linklist *h) { linklist *p; p = h; while(p != NULL) { printf("%c ", p->data); p = p->next; } printf("\n"); }
經過上述代碼能夠看出,尾插法確實比頭插法複雜點,多了兩個判斷。可是這是能夠解決的,經過添加一個頭節點,此節點不存放數據域,只是存放指向下個節點的指針域就是了。這樣就能夠免除掉兩次判斷。總體也要清晰點了。下面是增長一個頭節點後尾插法的實現代碼:調試
#include <stdio.h> #include <stdlib.h> typedef struct list { char data; struct list *next; }linklist; linklist *CreateList_End(); //尾插法建立鏈表 void ShowLinklist(linklist *h); //輸出顯示鏈表 int main(void) { linklist *head; printf("使用尾插法建立鏈表(改進版)\n"); printf("請依次輸入字符數據(‘#’表示輸入結束):\n"); head = CreateList_End(); //建立鏈表 ShowLinklist(head); //輸出鏈表 } linklist *CreateList_End() { linklist *head, *p, *e; char ch; head = (linklist*)malloc(sizeof(linklist)); e = head; //讓e指向頭節點 ch = getchar(); while(ch != '#') { p = (linklist*)malloc(sizeof(linklist)); p->data = ch; e->next = p; //把新節點添加到表尾 e = p; //把指針指向新節點 ch = getchar(); } e->next = NULL; //尾節點的指針域置空 return head; } void ShowLinklist(linklist *h) { linklist *p; p = h->next; while(p != NULL) { printf("%c ", p->data); p = p->next; } printf("\n"); }添加了一個頭節點後代碼是否是就要清晰點了呢?