單鏈表 C 實現 含虛擬頭節點

2022-02-24 16:01:12 字數 3673 閱讀 5597

鍊錶和陣列的最大區別在於鍊錶不支援隨機訪問,不能像陣列那樣對任意乙個(索引)位置的元素進行訪問,而需要從頭節點開始,乙個乙個往後訪問直到查詢到目標位置。

與順序表相對,鍊錶是一種鏈式儲存方式。單鏈表是實現順序表最簡單的一種鍊錶,根據是否包含虛擬頭節點,分為含虛擬頭節點和不含虛擬頭節點兩種方式。本文以含虛擬頭節點為例,用c++實現單鏈表資料結構adt。

節點:鍊錶的組成元素,每個節點包含資料域data和指標域next。例程為了簡化設計,data用int型別表示。

虛擬頭節點:鍊錶的第乙個節點,為了維護鍊錶操作方便,但不存放資料。

含虛擬頭節點的鍊錶優勢:所有的資料節點(除去頭節點)都是對等的,對鍊錶節點的api操作一般不影響頭節點本身指標變化(除去頭節點next域)。

缺點:需要額外考慮頭節點影響,比如isempty()判斷條件, 和length()是否對等(isempty <=> length==0?),頭節點對使用者是否可見,能否被使用者直接remove等。

含虛擬頭節點的單鏈表list如下圖所示,包含乙個虛擬頭節點v0,而v1~vn通過前驅節點next域進行鏈結,從而形成乙個單向鏈式結構。

虛擬頭節點v0,不包含資料;v1~vn包含資料,vn->next = null

名稱

描述

代表自定義符號

虛擬頭節點

不包含資料

vh/head

尾節點鍊錶的最後乙個節點,特徵:next=null

vn-1/tail

普通資料節點

包含具有實際意義資料的節點

v0~vn-1

長度包含實際意義資料節點數為n(不包括vh)

length

空鍊錶虛擬頭節點為空,即head=null

v0=null

位置從v0開始(vh後繼節點)開始計數0,直到vn-1(尾節點)的節點對應位置。範圍[0,n-1]

position

插入節點

在指定位置處插入節點,除插入節點及前驅和後繼,不改變鍊錶其他節點關係

insert

刪除節點

在指定位置處刪除節點, 除插入節點及前驅和後繼,不改變鍊錶其他節點關係

1. 鍊錶節點adt node.h

/**

* 單鏈表節點類

*/class node

;

2. 單鏈表adt linkedlist.h

/**

* 單鏈錶類

* @description 帶虛擬頭節點

*/class linkedlist

;

3. node實現 node.cpp

#include "node.h"

#include node::node()

node::node(node* newnext, int newvalue)

node::~node()

4. 鍊錶實現linkedlist.cpp

#include "linkedlist.h"

#include #include using namespace std;

linkedlist::linkedlist()

linkedlist::~linkedlist()

/** * 初始化鍊錶

*/status linkedlist::init()

return error;

}/**

* 銷毀鍊錶

* @description 與初始化操作相對, 刪除所有鍊錶節點, 包括頭節點

*/status linkedlist::destroy()

return ok;

} else

return n;

}/**

* 判斷鍊錶是否為空

* @description 判斷依據: 虛擬頭節點head == null

* 注: 長度為0 不代表鍊錶為空

*/bool linkedlist::isempty()

/** * 在指定位置生產節點, 並插入資料

* @param pos [in] 待插入位置. 從頭節點的後繼開始為0計數,所需要經過的節點數。範圍:0~n-1

* @param value [in] 待插入節點資料域

*/status linkedlist::insert(int pos, int value)

else if(pos >0 && pos <= length())

p->next = newnode;

} }else

if(!prenode)

curnode = prenode->next;

if(curnode)

return ok;

}/**

* 讀取指定位置節點資料

*/int linkedlist::getvalue(int pos)

else }

/** * 獲取位置節點的位址

* @param pos [in] 從頭節點的後繼開始為0計數,所需要經過的節點數。範圍:[0, n-1], n是鍊錶長度(有效資料節點數)

* @return 節點的位址

*/node* linkedlist::getaddress(int pos)

i ++;

curp = curp->next;

} return null;

}/**

* 搜尋第乙個出現的元素值的節點位置

* @param value 待查詢值

* @return 鍊錶第乙個節點的資料域=value的位置

* - error 錯誤

* - >=0 位置序號

*/int linkedlist::searchposition(int value)

cout<< "can't find the value in list"

return ok;

} return error;

}/**

* 清除鍊錶資料(不包含頭節點)

*/status linkedlist::clearlist()

head->next = null;

return ok;

}/**

* 順序列印鍊錶節點資料

*/status linkedlist::printlist()

} cout <

node *cur = pre->next; // current node

node *nxt = null; // successor node

while(cur != null)

// set the tail node

head->next->next = null;

// set the head node's next field

head->next = pre;

return ok;

}

6. 測試結果

可以看到已經實現了鍊錶基本的插入、列印、反轉等功能。

C語言無頭節點單鏈表的實現

鍊錶相對於順序表來說,插入和刪除更加方便,然而想要查詢乙個元素時卻沒有順序表方便。我們需要實現以下介面 ifndef linklist h define linklist h include include include include typedef int datatype typedef s...

單鏈表 無頭節點

就這書上 敲了一邊,加深印象,沒有頭結點的時候插入第乙個就有所不同了,而刪除時要找到前乙個,注意current link null 就這樣。include include include using namespace std struct linknode class list bool list...

C語言實現無頭節點的單鏈表

測試 singlelinkedlist.h標頭檔案 ifndef singlelinkedlist h include include include typedef int datatype typedef struct listnode listnode listnode initlist da...