基本資料結構(2) 鍊錶

2021-06-06 03:40:29 字數 3083 閱讀 9950

鍊錶開發於1955-56,由當時所屬於蘭德公司(英語:rand corporation)的艾倫紐維爾(allen newell),克里夫肖(cliff shaw)和赫伯特西蒙(herbert simon)在他們編寫的資訊處理語言(ipl)中做為原始資料型別所編寫。ipl被作者們用來開發幾種早期的人工智慧程式,包括邏輯推理機,通用問題解算器和乙個計算機象棋程式。

鍊錶的形態主要有單鏈表、雙向鍊錶和迴圈鍊錶。

鍊錶中最簡單的一種是單向鍊錶,它包含兩個域,乙個資訊域和乙個指標域。這個鏈結指向列表中的下乙個節點,而最後乙個節點則指向乙個空值。

來看單鏈表的實現:

template class linkedlist;

template class listelement

;template class linkedlist

;template listelement::listelement (t const& _datum, listelement* _next) :

datum (_datum), next (_next)

{}template t const& listelement::datum () const

template listelementconst* listelement::next () const

template linkedlist::linkedlist () :

head (0),

tail (0)

{}template void linkedlist::purge ()

tail = 0;

}template linkedlist::~linkedlist ()

template listelementconst* linkedlist::head () const

template listelementconst* linkedlist::tail () const

template bool linkedlist::isempty () const

template t const& linkedlist::first () const

return head->datum;

}template t const& linkedlist::last () const

return tail->datum;

}template void linkedlist::prepend (t const& item)

head = tmp;

} else

tail = tmp;

}template linkedlist::linkedlist (linkedlistconst& linkedlist) :

head (0),

tail (0)

}template linkedlist& linkedlist::operator = (

linkedlistconst& linkedlist)

} return *this;

}template void linkedlist::extract (t const& item)

if (ptr == 0)

throw invalid_argument ("item not found");

if (ptr == head)

head = ptr->next;

else

prevptr->next = ptr->next;

if (ptr == tail)

tail = prevptr;

delete ptr;

}template void linkedlist::insertafter (

listelementconst* arg, t const& item)

template void linkedlist::insertbefore (

listelementconst* arg, t const& item)

一種更複雜的鍊錶是「雙向鍊錶」或「雙面鍊錶」。每個節點有兩個連線:乙個指向前乙個節點,(當此「連線」為第乙個「連線」時,指向空值或者空列表);而另乙個指向下乙個節點,(當此「連線」為最後乙個「連線」時,指向空值或者空列表)

雙向鍊錶也叫雙鏈表。雙向鍊錶中不僅有指向後乙個節點的指標,還有指向前乙個節點的指標。這樣可以從任何乙個節點訪問前乙個節點,當然也可以訪問後乙個節點,以至整個鍊錶。一般是在需要大批量的另外儲存資料在鍊錶中的位置的時候用。雙向鍊錶也可以配合下面的其他鍊錶的擴充套件使用。

由於另外儲存了指向鍊錶內容的指標,並且可能會修改相鄰的節點,有的時候第乙個節點可能會被刪除或者在之前新增乙個新的節點。這時候就要修改指向首個節點的指標。有一種方便的可以消除這種特殊情況的方法是在最後乙個節點之後、第乙個節點之前儲存乙個永遠不會被刪除或者移動的虛擬節點,形成乙個下面說的迴圈鍊錶。這個虛擬節點之後的節點就是真正的第乙個節點。這種情況通常可以用這個虛擬節點直接表示這個鍊錶,對於把鍊錶單獨的存在陣列裡的情況,也可以直接用這個陣列表示鍊錶並用第0個或者第-1個(如果編譯器支援)節點固定的表示這個虛擬節點。

雙向鍊錶的實現相對於單鏈表來說要簡單,這裡就不列出實現**了。

在乙個迴圈鍊錶中, 首節點和末節點被連線在一起。這種方式在單向和雙向鍊錶中皆可實現。要轉換乙個迴圈鍊錶,你開始於任意乙個節點然後沿著列表的任一方向直到返回開始的節點。再來看另一種方法,迴圈鍊錶可以被視為「無頭無尾」。這種列表很利於節約資料儲存快取,假定你在乙個列表中有乙個物件並且希望所有其他物件迭代在乙個非特殊的排列下。

指向整個列表的的指標可以被稱作訪問指標。

迴圈鍊錶中第乙個節點之前就是最後乙個節點,反之亦然。迴圈鍊錶的無邊界使得在這樣的鍊錶上設計演算法會比普通鍊錶更加容易。對於新加入的節點應該是在第乙個節點之前還是最後乙個節點之後可以根據實際要求靈活處理,區別不大。當然,如果只會在最後插入資料(或者只會在之前),處理也是很容易的。

另外有一種模擬的迴圈鍊錶,就是在訪問到最後乙個節點之後的時候,手工的跳轉到第乙個節點。訪問到第乙個節點之前的時候也一樣。這樣也可以實現迴圈鍊錶的功能,在直接用迴圈鍊錶比較麻煩或者可能會出現問題的時候可以用。

基本資料結構 鍊錶

鍊錶 鍊錶與陣列的區別是鍊錶中的元素順序是有各物件中的指標決定的,相鄰元素之間在物理記憶體上不一定相鄰。採用鍊錶可以靈活地表示動態集合。鍊錶有單鏈表和雙鏈表及迴圈鍊錶。書中著重介紹了雙鏈表的概念及操作,雙鏈表l的每乙個元素是乙個物件,每個物件包含乙個關鍵字和兩個指標 next和prev。鍊錶的操作包...

基本資料結構 鍊錶

談到鍊錶之前,先說一下線性表。線性表是最基本 最簡單 也是最常用的一種資料結構。線性表中資料元素之間的關係是一對一的關係,即除了第乙個和最後乙個資料元素之外,其它資料元素都是首尾相接的。線性表有兩種儲存方式,一種是順序儲存結構,另一種是鏈式儲存結構。順序儲存結構就是兩個相鄰的元素在記憶體中也是相鄰的...

基本資料結構單向鍊錶

第一次發文章,謬誤之處請各位大佬指正。單向鍊錶的原理還是很簡單的而且和雙向鍊錶有很多相同之處 而且鍊錶和二叉搜尋樹有著很多聯絡以後我會在二叉搜尋樹的章節中寫一篇將二叉搜尋樹改寫成煉表的文章 只改變指標的指向 一下在 的注釋中寫出鍊錶的實現 include include struct node he...