數據結構-2(鏈表)

一、思維導圖

二、鏈表的反轉

    def reverse(self):"""思路:1、設置previous_node、current、next_node三個變量,目標是將current和previous_node逐步向后循環并逐步進行反轉,知道所有元素都被反轉2、但唯一的問題是:一旦current.next反轉為向前,current的后繼元素就將不再被記錄3、所以設置一個next_node用于在反轉開始前,current將后繼元素賦值給next_node。4、開始反轉5、反轉后將current和previous_node向后移動一次,然后重復以上3-5步驟:return:"""previous_node = Nonecurrent = self.headwhile current:next_node = current.next  # 記錄下一個節點,因為等會current的next要反轉了,先保存以免丟失current.next = previous_node  # 反轉節點previous_node = current  # 移動previouscurrent = next_node  # 移動next_node,由于next_node已經被記錄,所以即使current.next變成了前面的元素,但后面的元素也能找到。# print(current.data, end="--->")self.head = previous_node  # 最后把self.head補上

三、合并兩個有序鏈表

    def merge_sorted_lists(self, other_list):"""思路:1、創建i、j用于確定次數(之所以函數中的ij就能確定次數,是因為合并兩個有序列表實際上的目標是:將其中一個列表在與另一個列表的對比中,逐漸消耗到0,即排序完成),只要其中一個完成了不用管另一個完成了沒有直接加到尾部就行了,而ij正是這種設計,知道i,j的某一個達到對應列表的最大值(排序完成)才跳出第一個循環2、創建p、q兩個"指針"用于遍歷各自的鏈表3、翻轉兩個鏈表方便對比,因為這是單項升序表4、刪除鏈表1的原節點注意事項:1、當self鏈表為空時直接反轉other鏈表并拷貝,other為空則不變2、判空"""# 任意鏈表為空則無操作if self.size == 0 and other_list.size == 0:returnelif self.size == 0:# 如果 self 是空的,就將 other_list 反轉拷貝進來other_list.reverse()p = other_list.headwhile p:self.add_tail(p.data)p = p.nextself.reverse()self.size = other_list.sizereturnelif other_list.size == 0:return  # self 不變# 記錄 self 原有節點數量pre_size = self.size# 反轉兩個鏈表(升序→降序)self.reverse()other_list.reverse()# 準備兩個指針,遍歷 self 和 other_listq = self.headp = other_list.headi = j = 0while i < pre_size and j < other_list.size:if q.data >= p.data:self.add_tail(q.data)q = q.nexti += 1else:self.add_tail(p.data)p = p.nextj += 1# 4. 把剩下的節點繼續添加到尾部while i < pre_size:self.add_tail(q.data)q = q.nexti += 1while j < other_list.size:self.add_tail(p.data)p = p.nextj += 1# 5. 刪除 self 原來的 pre_size 個“舊節點”for _ in range(pre_size):self.delete_head()# 6. 恢復升序結構self.reverse()# 7. 更新 sizeself.size = pre_size + other_list.size

四、鏈表完整實現

"""
目的:解決順序表存儲空間有上限、刪除和插入效率低等問題(因為是按照簡單的列表索引儲存的,每次插入刪除需要騰位操作)。
鏈表:鏈式存儲的線性表,使用隨機的物理內存 存儲邏輯上相連的數據。注意點:
1、 用q進行處理時q指向的就是實際鏈表的Node對象,因為q和node都是可變對象,這實際上是一種引用綁定,兩者在賦值后指向同一個對象(Node)
2、 插入某個值時一定要先將下一個節點的位置給新節點保存,再將新節點的位置給前一個節點保存,順序不可變。因為下一個節點的位置只有上一個節點知道,如果上一個節點先改為保存新的節點,下一個節點的位置就沒有任何節點知道了。
"""class Node():"""1】 包含存儲數據元素的數據域2】有一個存儲下一個節點位置的位置域"""def __init__(self, data):self.data = data  # 普通節點的數據域self.next = None  # 普通節點的位置域class LinkedList():"""鏈表"""def __init__(self, node=None):self.size = 0  # 頭節點的數據域self.head = node  # 頭節點的位置域,用于記錄第一個節點的位置,可認為實際上就是下一個節點的整體(就通過next保存的位置來讀取下一個Node整體),\# 不單單是位置,這個整體包含了下一個節點的下一個節點的位置和下一個節點的數據。def add_head(self, value):"""功能:將頭插的方式插入到頭節點的后面注意事項:1、插入成功鏈表長度自增。2、申請Node節點,封裝:param:value:需要插入的節點的數據:return:"""node = Node(value)  # 創建一個全新的節點node.next = self.head  # 先將下一個節點的位置給新節點保存self.head = node  # 再將節點作為第一個節點給seld.head保存self.size += 1def add_tail(self, value):"""功能:將一個新的節點插入到鏈表的尾部:param value::return:"""if self.is_empty():self.add_head(value)  # 如果為空直接用add_headelse:q = self.head  # 創建一個q用于尋找節點尾部的位置while q.next != None:q = q.nextq.next = Node(value)  # 將找到的尾部None賦值為新的節點self.size += 1def add_index(self, index, value):"""通過q找到需要插入的位置冰進行處理,用q進行處理時q指向的就是實際鏈表的Node對象,因為q和node都是可變對象,這實際上是一種引用綁定,兩者在賦值后指向同一個對象(Node):param value::param index::return:"""if index > self.size + 1 or index <= 0:returnelse:if index == 1:self.add_head(value)else:q = self.headi = 1while i < index - 1:q = q.nexti += 1node = Node(value)node.next = q.next  # 先將新的next指向后面的node,否則后面的node的位置沒有人記錄鏈就斷了(故此行代碼不可與下行順序調換)q.next = nodeself.size += 1def delete_head(self):"""刪除第一個節點:return:"""if self.is_empty():returnelse:self.head = self.head.nextself.size -= 1def delete_tail(self):"""功能:尾刪,刪除最后一個節點:param value::return:"""# 判空if self.is_empty():print("刪除失敗")returnelif self.size == 1:  # 當鏈表只有一個結點時self.head = Noneelse:# 找到最后一個結點的前一個節點q = self.headi = 1while i < self.size - 1:q = q.nexti += 1# 刪除q.next = None  # q.next = q.next.nextself.size -= 1def delete_index(self, index):"""通過q找到需要插入的位置冰進行處理,用q進行處理時q指向的就是實際鏈表的Node對象,因為q和node都是可變對象,這實際上是一種引用綁定,兩者在賦值后指向同一個對象(Node):param value::param index::return:"""# 判空、判斷位置是否合理if self.is_empty() or index > self.size or index <= 0:print("位置錯誤")returnelse:if index == 1:  # 當索引為1時直接修改self.head.dataself.head = self.head.nextelse:q = self.head  # 創建q用于尋找需要修改的節點i = 1while i < index - 1:q = q.nexti += 1q.next = q.next.nextself.size -= 1def change_index(self, index, value):"""按位置修改:param index::param value::return:"""if self.is_empty() or index > self.size or index <= 0:print("錯誤")returnelse:if index == 1:  # 當索引為1時直接修改self.head.dataself.head.data = valueelse:q = self.head  # 創建q用于尋找需要修改的節點i = 1  # i用于確定循環次數while i < index - 1:q = q.nexti += 1q.data = value  # 對找到的節點進行賦值# 按值修改def change_value(self, o_value, n_value):""":param o_value::param n_value::return:"""if self.is_empty() or o_value == n_value:print("無需修改")returnelse:q = self.headwhile q:if q.data == o_value:q.data = n_valuereturnq = q.nextprint("查無此數據")def find_value(self, value):"""按值查找:param value::return:"""if self.is_empty():"鏈表為空空空空空空空空空"returnelse:q = self.headi = 1while i <= self.size:if q.data == value:return i + 1q = q.nexti += 1print("未找到數據")  # 如果到最后還沒有return說明沒有該數據return Nonedef is_empty(self):return self.size == 0def show(self):"""從頭到尾打印出節點的數據域中的數據,用q進行處理時q指向的就是實際鏈表的Node對象(但如果對q進行賦值則不是這樣,那就是普通的賦值而已并不改變實際的Node),因為q和node都是可變對象,這實際上是一種引用綁定,兩者在賦值后指向同一個對象(Node):return:"""if self.is_empty():returnelse:q = self.head  # 此時self.head已經在add_head時指向了第一個Node,故可以進一步訪問Node的data和下Node的next(即下一個Node)while q:print(q.data, end="->")q = q.nextprint()  # 換行def reverse(self):"""思路:1、設置previous_node、current、next_node三個變量,目標是將current和previous_node逐步向后循環并逐步進行反轉,知道所有元素都被反轉2、但唯一的問題是:一旦current.next反轉為向前,current的后繼元素就將不再被記錄3、所以設置一個next_node用于在反轉開始前,current將后繼元素賦值給next_node。4、開始反轉5、反轉后將current和previous_node向后移動一次,然后重復以上3-5步驟:return:"""previous_node = Nonecurrent = self.headwhile current:next_node = current.next  # 記錄下一個節點,因為等會current的next要反轉了,先保存以免丟失current.next = previous_node  # 反轉節點previous_node = current  # 移動previouscurrent = next_node  # 移動next_node,由于next_node已經被記錄,所以即使current.next變成了前面的元素,但后面的元素也能找到。# print(current.data, end="--->")self.head = previous_node  # 最后把self.head補上def merge_sorted_lists(self, other_list):pre_size = self.size # 先記錄一下排序之前的self.size,用于之后覺得執行頭刪操作的次數self.reverse()other_list.reverse()i = 0j = 0write = self.headq = self.head  # 創建一個q用于尋找節點的位置p = other_list.head  # 創建一個p用于尋找other節點的位置while write.next != None:write = write.nextwhile i < self.size and j < other_list.size:if q.data >= p.data:write.next = Node(q.data)write = write.nextq = q.nexti += 1else:write.next = Node(p.data)write = write.nextp = p.nextj += 1while j < other_list.size:write.next = Node(p.data)write = write.nextj += 1while i < self.size:write.next = Node(q.data)write = write.nexti += 1self.size=pre_size+other_list.sizefor i in range(pre_size):self.show()self.delete_head()self.reverse()if __name__ == '__main__':# 創建單向鏈表linkList = LinkedList()linkList.add_tail(10)linkList.add_tail(20)linkList.add_tail(30)linkList.add_tail(40)linkList.add_tail(50)linkList.add_tail(60)linkList_2 = LinkedList()linkList_2.add_tail(15)linkList_2.add_tail(25)linkList_2.add_tail(35)linkList_2.add_tail(45)linkList_2.add_tail(55)linkList_2.add_tail(65)linkList_2.add_tail(999)linkList_2.show()linkList.merge_sorted_lists(linkList_2)linkList.show()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914913.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914913.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914913.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ros2 標定相機

一個終端執行&#xff1a; ros2 run image_tools cam2image --ros-args -p width:640 -p height:480 -p frequency:30.0 -p device_id:-1 -r /image:/camera/image_raw另一個終端執行&#xff1a;8x6 是格子角點數量&#xff0c;0.028是格子尺寸 ros2 run camera_calibration …

IsaacLab學習記錄(二)

二、導入并訓練自己的機器人1、urdf等其他格式轉usd&#xff08;工具在./scrips/tools/&#xff09;???維度????URDF (Unified Robot Description Format)????USD (Universal Scene Description)????定位??機器人模型描述標準&#xff08;僅描述單機器人&…

基于Rust Softplus 函數實踐方法

Softplus 函數 Softplus 函數是神經網絡中常用的激活函數之一,定義為: ? Softplus函數導數 ? 是 sigmoid 函數。Softplus 處處可導,并且導數恰好是 sigmoid。 它是 ReLU 函數的平滑近似,具有連續可導的特性,適合需要梯度優化的場景。 數學特性 平滑性:導數為 Sig…

Ubuntu服務器安裝Miniconda

下載 Miniconda 安裝腳本&#xff08;如果能聯網&#xff09;wget https://repo.anaconda.com/miniconda/Miniconda3-py39_24.1.2-0-Linux-x86_64.sh -O Miniconda3.sh安裝 Miniconda 到 /opt/condabash Miniconda3.sh -b -p /opt/conda激活 conda/opt/conda/bin/conda init ba…

Java數組補充v2

一、數組基本概念1. 什么是數組數組是Java中用來存儲同類型數據的固定大小的連續內存空間的數據結構。2. 數組特點固定長度&#xff1a;一旦創建&#xff0c;長度不可改變相同類型&#xff1a;所有元素必須是同一數據類型索引訪問&#xff1a;通過下標&#xff08;從0開始&…

【PTA數據結構 | C語言版】前綴樹的3個操作

本專欄持續輸出數據結構題目集&#xff0c;歡迎訂閱。 文章目錄題目代碼題目 請編寫程序&#xff0c;利用前綴樹查找給定字符串是否在某給定字符串集合 S 中。 輸入格式&#xff1a; 輸入首先給出一個正整數 n&#xff08;≤1000&#xff09;&#xff0c;隨后 n 行&#xff0…

JAVA面試寶典 -《緩存架構:穿透 / 雪崩 / 擊穿解決方案》

&#x1f4a5;《緩存架構&#xff1a;穿透 / 雪崩 / 擊穿解決方案》 文章目錄&#x1f4a5;《緩存架構&#xff1a;穿透 / 雪崩 / 擊穿解決方案》&#x1f9ed; 一、開篇導語&#xff1a;為什么緩存是高并發系統的命脈&#xff1f;?1.1 緩存的核心價值緩存帶來的收益??&…

FPGA創意項目網頁或博客推薦

1. 綜合項目平臺(開源+教程) ① Hackster.io - FPGA專區 ?? https://www.hackster.io/fpga 特點: 大量基于FPGA的創意項目(如Zynq游戲機、視覺處理、機器人控制)。 提供完整教程(Vivado工程文件+代碼)。 推薦項目: FPGA-Based Oscilloscope(低成本示波器) V…

Go 程序無法使用 /etc/resolv.conf 的 DNS 配置排查記錄

在最近的一次部署中&#xff0c;我遇到一個奇怪的問題&#xff1a;Go 程序在運行時不使用 /etc/resolv.conf 中的 DNS 設置&#xff0c;導致服務無法正常訪問域名。這篇文章記錄下完整的排查過程和最終的解決方案。1. 問題現象我有一個部署在 KVM 虛擬機內的 Go 應用&#xff0…

微服務相關問題(2)

1、Spring Cloud相關常用組件注冊中心&#xff08;nacos、Eureka等&#xff09;、負載均衡&#xff08;Ribbon、LoadBalancer&#xff09;、遠程調用&#xff08;feign&#xff09;、服務熔斷&#xff08;Sentinel、Hystrix&#xff09;、網關&#xff08;Gateway&#xff09;2…

安全初級2

一、作業要求 1、xss-labs 1~8關 2、python實現自動化sql布爾育注代碼優化(二分查找) 二、xss-labs 1~8關 1、準備 打開小皮面板&#xff0c;啟動MySQL和apacher 下載 xss-labs&#xff0c;并解壓后放到 phpstudy_pro 的 WWW 目錄下&#xff0c;重命名為 xss-labs 訪問鏈…

基礎算法題

基礎算法題 鏈表 1.1反轉鏈表 描述&#xff1a; 描述 給定一個單鏈表的頭結點pHead(該頭節點是有值的&#xff0c;比如在下圖&#xff0c;它的val是1)&#xff0c;長度為n&#xff0c;反轉該鏈表后&#xff0c;返回新鏈表的表頭。 數據范圍&#xff1a; 0≤&#xfffd;≤…

Android 15 源碼修改:為第三方應用提供截屏接口

概述 在 Android 系統開發中,有時需要為第三方應用提供系統級的截屏功能。本文將詳細介紹如何通過修改 Android 15 源碼中的 PhoneWindowManager 類,實現一個自定義廣播接口來觸發系統截屏功能。 修改方案 核心思路 通過在系統服務 PhoneWindowManager 中注冊自定義廣播監…

20250717 Ubuntu 掛載遠程 Windows 服務器上的硬盤

由 DeepSeek 生成&#xff0c;方法已經驗證可行。 通過網絡掛載Windows共享硬盤&#xff08;SMB/CIFS&#xff09; 確保網絡共享已啟用&#xff1a; 在Windows電腦上&#xff0c;右鍵點擊目標硬盤或文件夾 → 屬性 → 共享 → 啟用共享并設置權限&#xff08;至少賦予讀取權限&…

深度學習圖像增強方法(二)

三、直方圖均衡化 1. 普通直方圖均衡化 直方圖均衡化的原理是將圖像的灰度直方圖展平,使得每個灰度級都有更多的像素分布,從而增強圖像的對比度。具體步驟如下: 計算灰度直方圖:統計圖像中每個灰度級的像素數量。 計算累積分布函數(CDF):計算每個灰度級的累積概率。 映…

QT——信號與槽/自定義信號與槽

1 信號與槽基本介紹 提出疑問&#xff0c;界面上已經有按鍵了&#xff0c;怎么操作才能讓用戶按下按鍵后有操作上的反應呢&#xff1f; 在 Qt 中&#xff0c;信號和槽機制是一種非常強大的事件通信機制。這是一個重要的概念&#xff0c;特別是對于初學者來說&#xff0c;理解它…

Spring原理揭秘--Spring的AOP

在這之前我們已經介紹了AOP的基本功能和概念&#xff0c;那么當AOP集成到spring則會發生改變。Spring AOP 中的Joinpoint&#xff1a;之前提高了很多Joinpoint的類型&#xff0c;但是在spring中則只會有方法級別的Joinpoint&#xff0c;像構造方法&#xff0c;字段的調用都沒適…

C++學習筆記五

C繼承//基類 class Animal{};//派生類 class Dog : public Animal{};#include<iostearm> using namespace std;//基類 class Shape{public:void setwidth(int w){width w;}void setheight(int h){height h;}protected:int width;int height;}//派生類 class Rectangle …

AndroidStudio環境搭建

一、AndroidStudio下載 正常百度出來的站會自動翻譯成中文&#xff0c;導致歷史版本的界面總是顯示不出可下載的地方&#xff0c;點擊成切回英文&#xff0c;就能看出了。 歷史版本&#xff1a;https://developer.android.google.cn/studio/archive

Java大廠面試實錄:從Spring Boot到AI大模型的深度技術拷問

場景&#xff1a;互聯網大廠Java后端面試 面試官&#xff08;嚴肅&#xff09;&#xff1a;小曾&#xff0c;請坐。今天主要考察Java后端技術棧&#xff0c;包括微服務、大數據、AI等。我們先從簡單問題開始。 小曾&#xff08;搓手&#xff09;&#xff1a;好嘞&#xff01;面…