●
不帶頭節點:此時頭指針指向第一個節點
h->a1->a2->a3->…… // 頭指針存放的是第一個節點的地址,即h,也就是說(*h)表示的是第一個節點
帶頭結點:此時頭指針指向頭結點
h->headnode->a1->a2->a3->…… // 頭指針存放的是頭結點的地址,也就是說(*h)表示的是頭結點
//初始化鏈表 Node* initList() { Node *head = (Node*)malloc(sizeof(Node)); head->next = NULL; //此時 head 表示的就是頭指針,之中存放的就是頭結點的地址, return head; //所以 head->next 表示的為頭結點的下一個節點,也就是首元節點。 }
● 空表的比較
//不帶頭節點 h = NULL; // h 表示的是第一個節點的地址,h = NULL 表示第一個節點的地址為空,也就是空表 // 帶頭結點 h->next = NULL; // h 表示的是頭結點的地址,h->next 就是頭結點的下一個節點,即首元節點為空,也就是空表
● 添加第一個節點的區別
Node *newnode = (Node*)malloc(sizeof(Node));
//帶頭結點 newnode->next = h-> next; h->next = newnode; //不帶頭結點 newnode->next = h ; h = newnode ;
●反思:常在網上看到,不帶頭結點的方式比帶頭結點的方式在處理第一個節點的時候會繁瑣一點,舉個例子。
typedef struct Node { ListTpye data; struct Node *next; }Node, *LinkList; //添加節點(頭插法) int add(LinkList *h, int data) { if ((*h) == NULL) return 0; Node *node = (Node*)malloc(sizeof(Node)); node->data = data; node->next = *h; (*h) = node; return 1; }
從此可以看出不帶帶節點的好處了,不帶頭節點時,使用頭插法插入節點時我們要不停更改頭指針,讓他指向新節點,並且傳入的值是頭指針的指針,很容易混淆。
總結:總的來說,就是帶頭結點時不管是否為空表,頭指針的值都不會變化,都指向頭結點。而不帶頭結點則需要根據不同情況來修改頭指針的值。所以操作不統一,有所不便,所以絕大數時候使用帶頭結點的方式較為方便。