結點類型:
typedef int datatype;
typedef struct NODE{
datatype data;
struct NODE *next;
}Node,*LinkList;
1、不帶頭結點的頭插入法創建鏈表。
每創建一個結點,都使該結點成為頭結點,這樣頭結點不斷地向前移動,就可以創建一個沒有特定頭結點的鏈表。
首先創建的結點,會出現在整個鏈表的最末端,所以數據的寫入是逆序的。
【開始的時候,head要初始化為NULL】
LinkList LinkListCreate(const int n) { int i; LinkList head; Node *p; head = NULL; for(;i<n;i++) { p = (Node*)malloc(sizeof(Node)); if(NULL == p) perror("ERROR"); scanf("%d",&p->data);
p->next = head; head = p; } }
開始時候,head 是一個空指針,創建一個結點p。現在head是指向一個鏈表的頭結點,創建了一個新的結點p,向前插入。所以要p->next = head;然后再使head成為新鏈表的頭結點。
2、不帶頭結點的未插入法創建鏈表。
創建這樣的鏈表,首先指向頭結點的指針不能移動,所以需要創建一個一直指向尾結點的指針rear。
LinkList LinkListCreate(const int n) { int n= 0; //創建一個一直指向頭結點,一直指向尾結點的指針。 LinkList head; Node *p,*rear; rear = head = NULL; for(;i<n;i++) { p = (Node*)malloc(sizeof(Node)); scanf("%d",&p->data); if(NULL == head) //創建的第一個結點。 else rear->next = p;//鏈表非空 rear = p;//移動尾指針 }
rear->next = NULL;//最后將鏈表的結尾設置為NULL。 }
【值的注意的就是,最后設置鏈表的結尾為NULL】
3、創建帶結點的頭插入鏈表。
所謂的頭結點是不存儲數據的,他只是個指針結點。可以在該頭結點存儲一些這個鏈表的整體信息。比如鏈表的結點數量。
這種
創建方法跟第一種方法是一樣的思路。
1 LinkList LinkListCreate(const int n) 2 { 3 int i = 0;LinkList p; 4 LinkList head = (Node*)malloc(sizeof(Node)); 5 head->next = NULL; 6 7 for(;i<n;i++) 8 { 9 p = (Node*)malloc(sizeof(Node)); 10 scanf("%d",&p->data); 11 p->next = head->next; 12 head->next = p; 13 } 14 15 return head; 16 }
【純C語言,是要求所有的變量在使用的時候,必須在作用域的開始處定義。】
4、帶頭結點的尾插入法創建鏈表。
開始創建的時候,rear = head. rear->next = p; rear = p;最后要使的rear->next = NULL;
LinkList LinkListCreate(const int n) { int i = 0;Node *p,*rear; LinkList head = (Node*)malloc(sizeof(Node)); rear = head; for(;i<n;i++) { p = (Node*)malloc(sizeof(Node)); scanf("%d",&p->data); rear->next = p; //尾指針 指向新建結點 rear = p;//rear指針移動 } rear->next = NULL; return head; }
歡迎指正……
有的吧友給我建議說一下有頭結點的好處,下面是我的個人所思:、
頭結點:如果在鏈表的開始結點之前附加一個結點,並稱它為頭結點,那么會帶來以下兩個優點:
a、 由於開始結點的位置被存放在頭結點的指針域中,
所以在鏈表的第一個位置上的操作就和在表的其它位置上
的操作一致,無需進行特殊處理;
b、無論鏈表是否為空,其頭指針是指向頭結點在的
非空指針(空表中頭結點的指針域為空),因此空表和
非空表的處理也就統一了。
基於上述兩點優點,跟人覺得以后在建立鏈表的時候,創建帶頭結點的鏈表。