[英]Confusion about the first and the last elements of a linked list
對於將元素添加到鏈表的前面還是后面,我感到困惑。 假設我們有一個鏈表,如下所示: x->a->c->v
; 在這里, x
是第一個元素還是最后一個元素? 其次,如果我想添加x->a->c->v->h
或h->x->a->c->v
怎么辦? 當我遇到以下問題時,這使我感到困惑:
考慮實現循環單鏈列表數據結構。 假設循環鏈表的指針
ptr
指向最后一個節點,其link
字段指向鏈表的第一個節點。 完成以下指定的add(...)
和delete(...)
的算法。 您可以編寫偽代碼或C代碼。 假定鏈表列表節點結構的以下聲明:typedef struct list_node* list_pointer; typedef struct list_node { int value; list_pointer link; } list_pointer ptr = NULL;
注意,如果循環鏈表為空,則其指針
ptr
將設置為NULL
。// Add node at the front of the circular list ptr; ptr points at the last node in the list void add(list_pointer *ptr, list_pointer node) { ... } // Delete the front node from the list ptr list_node delete(list_pointer *ptr) { ... }
第一個元素是x
,因為這是通過遵循next
指針鏈來遍歷列表時將獲得的第一個元素。
當添加到鏈接列表時,可以在第一個元素之前或最后一個元素之后添加。 在第一個元素之前添加會更有效,因為您不必跟隨next
指針的整個鏈來查找結尾。
用於鏈表的常用術語是head
和tail
。
在非循環列表中,就像您在問題中顯示的那樣, head
節點將是列表中沒有其他節點指向的節點,因此您需要另一個指針listHead
指針來指向它。 因為您通常從listHead
指向的節點開始遍歷列表,所以也可以將head
節點視為列表中的first
節點。
在非循環列表中, tail
節點是不指向任何其他節點的節點。 可以將其視為列表中的last
節點。
現在,在循環列表中,就像您鏈接的文本中引用的列表一樣, head
和tail
以及first
和last
可能會稍微復雜一些,因為每個節點都指向另一個節點,並且另一個節點指向該節點。 循環列表的開始和結束位置通常由列表的排序順序(如果有一個或其他一些遍歷條件來控制列表的排序順序)決定。
基本的循環列表可以包括listHead
指針,該指針指向您在瀏覽列表時應訪問的first
節點。
一些更高級的循環列表將變為使用listTail
指針,指向列表的最后一個節點。 這樣做是因為,有了循環列表,如果您有指向tail
節點的指針,就很容易到達head
節點,因為tail
節點將指向head
節點。 因此,通過提供一個指向tail
節點,您可以快速進入到雙方last
和first
列表中的節點。 這是鏈接文本所描述的數據結構的類型。
現在,對於您有關插入的問題,這完全取決於您以及如何使用列表。 如果列表是無序的,則插入新節點作為列表的新head
要快得多。 但是,如果要實現先進先出列表,則可能要插入新節點作為列表的新tail
。 當然,如果列表中有一個訂單,則基於每個節點包含的一些數據,那么您想要在列表中找到正確的位置以插入新節點以保留該訂單。
您可以選擇自己的列表方向。 通常,通過將指向前一個和下一個節點的指針命名為previous and next。 您如何命名它們確定順序。 如果您有一個雙向鏈接列表,則您的節點同時具有兩個指針。
但是,您始終存儲指向第一個和最后一個元素的指針。 這樣,您可以具有push_front
, pop_front
, push_back
和pop_back
函數。
但是,如果您有一個轉發列表,(您僅將next
指針存儲在您的節點中,那么您將沒有pop_back
,因為您的最后一個節點沒有到上一個節點的鏈接,並且您不知道新的最后一個元素變為。
所以
push_front
, pop_front
, push_back
, push_front
, push_back
, pop_back
, push_front
, pop_front
, push_back
, pop_back
,
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.