日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用循环链表实现一个通讯录的管理程序_【LeetCode链表题型总结】

發布時間:2025/3/11 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用循环链表实现一个通讯录的管理程序_【LeetCode链表题型总结】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

點擊上方藍字,關注公眾號

鏈表概念的講解

鏈表是什么

鏈表是一種線性數據結構,每個節點都存有數據,通過指針將各個節點鏈接在一起。

鏈表的性質

  • 一致性: 每個節點有相同的數據結構,相同的數據大小,內存中占據相同的大小,存儲相同的數據類型。
  • 有序性: 節點之間的相對順序固定,排在某節點前面的節點就是它的前驅,后面的節點就是它的后繼,所以定義里面有'線性'。

鏈表的分類

鏈接方式分類:單向鏈表,雙向鏈表。

ps: 代碼展示只用單鏈表舉例。

單鏈表結構

單鏈表中的每個結點包含數據+指向后繼節點的指針,通過這種方式,單鏈表將所有結點按順序組織起來。

節點定義

class?Node(object):"""單鏈表結構的Node節點"""
????def?__init__(self,?data,?next_node=None):"""Node節點的初始化方法。
????????data:存儲的數據
????????next:下一個Node節點的引用地址
????????"""
????????self.data?=?data
????????self.next?=?next_node

雙鏈表結構

雙鏈表中的每個節點包含數據+指向前驅和后繼的指針。

鏈表的基本操作

鏈表基本操作: ?插入,搜索,刪除。以下分別講每個操作是如何操作的,時間復雜度多少,為什么是那么多,根據時間復雜度判斷鏈表的適合場景。

查找

按照索引/值查找: 遍歷找到對應的位置/值,然后返回該節點。

#?按照值查找
node?=?head_nodewhile?node.data?!=?value:
????node?=?node.next_node#?按照索引查找
pos?=?0while?pos?!=?index:
????node?=?node.next_node
????pos?+=?1

時間復雜度:是線性遍歷的,所以時間復雜度是O(n)。因為時間復雜度相對較高,所以在大量數據需要經常用檢索的時候就不要用鏈表了。

插入

按照index插入

1.先創建新節點new_node

2.找到要插入的位置的前驅節點pre

3.新節點new_node指向pre的后繼節點

4.pre指向新節點

new_node.next?=?pred.next
pred.next?=?new_node

時間復雜度:由于第2步要線性遍歷去找index位置,所以時間復雜度是O(n)。如果插入在頭部,就不需要找位置,時間復雜度是O(1)。

刪除

如何做刪除的?

1.找到待刪節點的前驅pred

2.把它的前驅節點的后繼指向待刪節點后繼的后繼

pred.next?=?pred.next.next

時間復雜度:因為要去找前驅,所以線性遍歷,時間復雜度是O(n)。如果刪除頭部,就不需要找位置,時間復雜度是O(1)。

鏈表常見的考點: 啞節點(邊界條件)- 用于簡化邊界情況,鏈表為空或鏈表的頭結點和尾節點。解決辦法,自己創建一個啞節點,然后把它的后繼連接原節點。

鏈表的實際應用,通常用于順序記錄的存儲,無需提前分配空間,僅適用小規模數據存儲。

對于適用的操作屬性來說,鏈表適合查找少,無需排序的使用場景,原因:是鏈表的查找效率不高,通過調整指針可以快速調節節點的相對位置。

業界應用: 小規模日志記錄(通話記錄或通訊錄),讀到內存中后可以以鏈表的方式進行存儲;操作系統中內存快的緩存也可以用鏈表來實現,LRU緩存(利用了鏈表快速調整相對位置優勢)。

模式識別

以下這些適用解決鏈表相關問題。

runner and chaser類型題目中有關鍵詞: 要尋找每個特定位置/相對位置。就用后移速度不同的快慢指針來解決使以下文章用到這個方法:
  • 【LeetCode-19-Remove Nth Node From End of List】刪除鏈表的倒數第N個節點

  • 【LeetCode-141-Linked List Cycle】環形鏈表

  • 【LeetCode-876-Middle of the Linked List】鏈表的中間節點

遍歷并處理節點: 處理包括交換,改數值,改指針,刪除等等這類問題的處理方式是每次操作都是當前節點或某類節點,每次處理單個或一對節點;處理的時候,先改變前驅指針,再改變當前節點指針,否則當前節點的next信息改變完之后就不對了,通過先改變前驅的指針到達一個保存狀態的目的。要動一個元素的后繼之前,先保存它的后繼。
  • 【LeetCode24. Swap Nodes in Pairs】兩兩交換鏈表中的元素

  • 【LeetCode-25-Reverse Nodes in k-Group】K 個一組翻轉鏈表

  • 【LeetCode-143-Reorder List】重排鏈表,次頭條。

處理兩個或多個鏈表處理方式是用while循環進行常規處理,循環條件是list1非空并且list2非空,當循環跳出后處理剩下的非空列表。循環至空,再處理剩余。
  • 【LeetCode-21. Merge Two Sorted Lists】合并兩個有序鏈表?

應用遞歸處理(涉及鏈表倒序處理問題)解決當前問題依賴于存在的相似結構的子問題;利用調用函數本身,先解決子問題,再利用子問題的結果解決當前的問題,遞歸的出口通常是問題的初始條件n=1的情況。鏈表問題一旦需要倒序處理或與樹之間的數據結構進行相互轉換往往會用到遞歸,或者用棧來解決。LeetCode369,426,因為這兩道題要會員才能做,我不能做,所以沒有寫題解。

自己實現一個單鏈表類

實現插入查找刪除的功能。

class?ListNode(object):
????def?__init__(self,?value):"""
????????value:?節點的數據值
????????next:?節點的后繼
????????"""
????????self.value?=?value
????????self.next?=?None
class?MyLinkedList(object):
????def?__init__(self):"""
????????Initialize?your?data?structure?here.
????????"""
????????self.head?=?ListNode(0)?#?用啞結點來當頭節點,方便處理插入和刪除的邊界情況。
????????self.size?=?0
????def?get(self,?index):"""按照索引查找
????????Get?the?value?of?the?index-th?node?in?the?linked?list.?If?the?index?is?invalid,?return?-1.
????????:type?index:?int
????????:rtype:?int
????????"""#?異常情況:?如果索引無效?|?索引超出范圍if?index?=?self.size:return?-1
????????node?=?self.headfor?_?in?range(index?+?1):?#?記得鏈表的頭結點是啞結點,所以range后界要+1
????????????node?=?node.nextreturn?node.value?#?是返回節點值
????def?addAtHead(self,?val):"""添加到頭節點
????????Add?a?node?of?value?val?before?the?first?element?of?the?linked?list.?After?the?insertion,?the?new?node?will?be?the?first?node?of?the?linked?list.
????????:type?val:?int
????????:rtype:?None
????????"""
????????self.addAtIndex(0,?val)
????def?addAtTail(self,?val):"""添加到尾節點
????????Append?a?node?of?value?val?to?the?last?element?of?the?linked?list.
????????:type?val:?int
????????:rtype:?None
????????"""
????????self.addAtIndex(self.size,?val)
????def?addAtIndex(self,?index,?val):"""按照索引添加node
????????:type?index:?int
????????:type?val:?int
????????:rtype:?None
????????"""#?異常情況:?如果索引無效?|?索引超出范圍if?index?=?self.size?+?1:return?#?什么都不做#?找到要加入節點的前驅節點
????????node?=?self.headfor?_?in?range(index):?
????????????node?=?node.next#?加入新節點
????????new_node?=?ListNode(val)?#?創建新節點
????????new_node.next?=?node.next
????????node.next?=?new_node#?鏈表的總數加1
????????self.size?+=?1
????def?deleteAtIndex(self,?index):"""刪除節點
????????因為刪除操作的流程是,待刪節點node的前驅pre,改變pre后繼節點到node的后繼節點,所以找的節點應該是pre
????????:type?index:?int
????????:rtype:?None
????????"""#?異常情況:?如果索引無效?|?索引超出范圍if?index?=?self.size:return?#?什么都不做#?找到要刪除的節點
????????node?=?self.headfor?_?in?range(index):?#?找到待刪節點的前驅節點,因為我們已經在頭部加了啞結點,所以真正的頭部節點是不用單獨處理的,按照常規刪節點的方式處理
????????????node?=?node.next#?刪除待刪節點
????????node.next?=node.next.next#?鏈表的總數減1
????????self.size?-=?1

參考資料:

- 力扣

原創文章,歡迎轉載,轉載請在公眾號菜單欄查看【聯系我】。

? ? ? ? ? ? ? 喜歡本文的小伙伴點【在看】分享給你的朋友?↓↓↓

總結

以上是生活随笔為你收集整理的使用循环链表实现一个通讯录的管理程序_【LeetCode链表题型总结】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。