歡迎**。
一、鍊錶的基本概念
這一節講解一下c語言中的鍊錶,並且只講解單鏈表。在單鏈表中,每乙個節點包含乙個指向鍊錶下乙個節點的指標。鍊錶最後乙個節點的指標欄位的值為null,提示鍊錶後面不再有其他節點。在你找到鍊錶的第乙個節點後,指標就可以帶你訪問剩餘的所有節點。為了記住鍊錶的起始位置,可以使用根指標(root pointer)。根指標指向鍊錶的第乙個節點。根指標只是乙個指標,它不包含任何資料。示意圖如下:
所以,我們可以根據鍊錶的結構,建立對應的結構體:
typedef struct node node;
2. 每個節點中又有自己的值,儲存在value中。
在上面的圖中,這些節點相鄰在一起,這是為了顯示鍊錶所提供的邏輯順序。事實上,鍊錶中的節點可能分布於記憶體中的各個地方。各節點在物理上是否相鄰並沒有什麼關係,因為程式始終用鏈(指標)從乙個節點移動到另乙個節點。
二、 單鏈表的插入
假設我們有乙個新值12,想把它插入到上圖的鍊錶中。思路是非常清晰的,從鍊錶的起始位置開始,跟隨指標直到找到第乙個值大於12的節點,然後把這個新值插入到那個節點之前的位置。但是前乙個節點的指標字段必須進行修改以實現這個插入,但是我們已經越過了前乙個節點,無法返回去。所以我們可以始終儲存乙個指向鍊錶當前節點之間的那個節點的指標。
所以分析可知,**中需要三個指標變數,用來指向不同的節點。
1. node *current, 用來指向當前的節點。
2. node *previous, 用來指向前乙個節點。
3. node *new, 用來指向新分配的節點。
下面,我使用流程圖來分析插入過程。
在插入之前的狀態(current指向第乙個節點):
現在current->value 是5, 小於12。所以previous和current的指標都需要向前移動乙個,如下圖:
現在current->value 是10, 還是小於12。所以previous和current的指標都需要向前移動乙個,如下圖:
此時,current->value的值是15,大於12。我們需要建立新的節點,準備插入:
把這個節點插入到鍊錶中需要兩個步奏:
1. 使新節點指向將成為鍊錶下乙個節點的節點,也就是我們所找到的第乙個值大於12的那個節點。**就是
new->link = current;
效果圖如下:
2. 讓previous指標所指向的節點指向這個新節點。**就是
previous->link = new;
效果圖如下:
這樣,單鏈表的基本插入操作就算完成了,**如下:
int insert(node *current, int new_value)
// 分配新插入的節點
new = (node *)malloc(sizeof(node));
if (new == null)
new->value = new_value;
// 把新節點插入到鍊錶中
new->link = current;
previous->link = new;
return 1;
}
但是,**還是有缺陷的,我們現在考慮邊緣值的問題。
1. 插入的值,大於鍊錶中值的最大值。
2. 插入的值,小於鍊錶中值的最小值。
先來分析第一種情況,假設插入的值是20。while迴圈執行到最後,current->value的值是15,執行current = current->link; 後, current 則為null,然後又嘗試執行while語句中的判斷,而此時current為null,執行current->value 則報錯了。所以我們需要對判斷條件進行限制。**如下:
while (current != null && current->value < new_value)
這樣,插入20之後的流程圖如下:
再來分析第二種情況,假設插入的值是3. 在while迴圈的條件永遠不成立了,因為current指標預設就是指向第乙個節點的,我們無法操作root,也就是不可以操作根指標。
為了在鍊錶的起始位置插入乙個節點,函式必須修改根指標。所以我們需要定義乙個指向根指標的指標。所以這個指標是指向指標的指標。我們可以定義為 node **rootp;
所以我們可以修改**如下:
int insert(node **rootp, int new_value)
// 分配新插入的節點
new = (node *)malloc(sizeof(node));
if (new == null)
new->value = new_value;
// 把新節點插入到鍊錶中
new->link = current;
if (previous == null) else
return 1;
}
修改**之後,初始流程圖如下:
插入含有值3的這個節點後的流程圖如下:
c語言 鍊錶 C語言鍊錶例項 玩轉鍊錶
下圖為最一簡單鍊錶的示意圖 第 0 個結點稱為頭結點,它存放有第乙個結點的首位址,它沒有資料,只是乙個指標變數。以下的每個結點都分為兩個域,乙個是資料域,存放各種實際的資料,如學號 num,姓名 name,性別 和成績 score 等。另乙個域為指標域,存放下一結點的首位址。鍊錶中的每乙個結點都是同...
c語言鍊錶 鍊錶
在儲存一大波數的時候,我們通常使用陣列,但有時候陣列顯得不夠靈活,比如有一串已經從小到大排序好的數 2 3 5 8 9 10 18 26 32 現在需要往這串數中插入6使其得到的新序列仍符合從小到大排列。如果我們使用陣列來實現這一操作,則需要將8和8後面的數字都依次往後挪一位,如果你覺得這幾個數不算...
c語言 鍊錶 C語言之鍊錶入門
鍊錶三要素 1 頭指標 head 是用來說明鍊錶開始了,頭指標就代表鍊錶本身 所以以後要訪問鍊錶,就要訪問頭指標 2 結點 node 鍊錶中每乙個結構體變數 3 尾指標 用來說明鍊錶的結束 它是乙個空指標,null include includetypedef struct stud 定義了乙個結構...