相信很多剛找工作時的同學,都遇到過面試時被問鏈表的情景,有些面試官還喜歡直接要你在紙上寫。今天,就給大家詳細講解下鏈表。
鏈表實現了物理存儲上非連續,可以通過當前節點索引下一個節點,最後一個元素爲空,在C語言實現上,用指針來索引下一個節點,今天也通過C語言來講解鏈表的實現。
在上篇中,我們來實現一個簡單版的,假如每個節點存儲一個int的值。則一個節點可以這樣定義:
typedef struct Node
{
int val;
struct Node *next;
}Node;
這樣,一個節點不但保存值信息,還保存下一個節點的信息。
所有節點鏈接起來,我們稱爲鏈表。
頭節點
我們把鏈表中的第一個節點稱爲頭節點,
尾節點 自然把最後一個節點稱爲尾節點。
在實際的應用中,爲了操作的方便,第一個節點經常不用來存儲有用信息,而是作爲索引方便,尾節點也是。
今天的代碼,就假設鏈表中的第一個節點不存儲有用信息,而是爲了操作方便,來演示鏈表的頭插法。
先定義一個鏈表
typedef struct LinkList
{
struct Node head;
struct Node tail;
}LinkList;
爲了頭插法和尾插的方便,我們在尾部也增加一個輔助節點。
頭插法代碼
LinkList* LinkListInsertHead(LinkList *mylist, int inval)
{
struct Node *node = (Node*)malloc(sizeof(Node));
node->val = inval;
if (mylist->head.next != &mylist->tail)
{
node->next = mylist->head.next;
mylist->head.next = node;
}
else
{
mylist->head.next = node;
node->next = &mylist->tail;
mylist->tail.next = node;
}
return mylist;
}
尾插法
LinkList* LinkListInsertTail(LinkList *mylist, int inval)
{
if (!mylist)
return NULL;
Node *node = (Node*)malloc(sizeof(Node));
node->val = inval;
Node *tmp = mylist->tail.next;
tmp->next = node;
node->next = &mylist->tail;
mylist->tail.next = node;
return mylist;
}
說明:
尾節點指向的是有效節點中的最後一個,所以初始化的時候,指向的是頭節點。
所以,頭插法的時候,要判斷鏈表中是否爲空,如果爲空,尾節點指向的節點就是新插入的節點了,同時頭節點也指向的是新插入的節點。
尾插法的時候,就比較簡單,找到最後一個節點,讓最後一個節點指向新節點,然後尾節點也指向新節點。
代碼:
代碼地址 https://github.com/jxdeng3264/Blog
【讚賞】