詳解Golang中鏈表的創(chuàng)建和讀取
鏈表的相關(guān)知識(shí)
鏈表有時(shí)會(huì)具有頭節(jié)點(diǎn),頭節(jié)點(diǎn)的指針指向第一個(gè)節(jié)點(diǎn)的地址,其本身的數(shù)據(jù)域可以根據(jù)自己的選擇進(jìn)行賦值
接下來(lái)我將以將int轉(zhuǎn)換為鏈表為例進(jìn)行演示,如果有什么地方可以改進(jìn),也希望路過(guò)大神能夠指出
鏈表的創(chuàng)建
鏈表的結(jié)構(gòu)定義一般如下,即由本身的數(shù)據(jù)和指向下一個(gè)節(jié)點(diǎn)的指針構(gòu)成
type ListNode struct { Val int Next *ListNode//不能直接賦值listnode,避免產(chǎn)生嵌套引用 }
鏈表的創(chuàng)建(每個(gè)節(jié)點(diǎn)存儲(chǔ)一位數(shù)字),在創(chuàng)建的過(guò)程中 我們需要設(shè)置中間的可變節(jié)點(diǎn),不然我們可能會(huì)丟失對(duì)鏈表的第一個(gè)節(jié)點(diǎn)的索引,以下的例子中我們就使用middle為中間節(jié)點(diǎn);將head設(shè)置為頭節(jié)點(diǎn),并代表完整的鏈表
模擬方式建立
我們利用迭代的方法,只要還存在num,就更新創(chuàng)建一個(gè)新的節(jié)點(diǎn)
// 嘗試建立有頭節(jié)點(diǎn)的鏈表,關(guān)鍵在于賦值給middle.next func CreateList(nums int) *ListNode { Head := new(ListNode) //這代表一整個(gè)鏈表,并通過(guò)這里的頭節(jié)點(diǎn)進(jìn)行標(biāo)注,方便該鏈表的引用 middle := Head //middle視作Head鏈表的中間節(jié)點(diǎn),其一直改變 for nums > 0 { middle.Next = &ListNode{Val: nums % 10}//頭節(jié)點(diǎn)賦值方法 fmt.Printf("middle.Val: %v\n", middle.Val) middle = middle.Next nums /= 10 } return Head }
鏈表的遞歸創(chuàng)建
// 遞歸建立鏈表 func RecurCreateList(nums int) *ListNode { //在遞歸時(shí)好像不需要單獨(dú)保存頭節(jié)點(diǎn)位置,后續(xù)的位置會(huì)遞歸存儲(chǔ)在next中,不用考慮被覆蓋的問(wèn)題 middle := new(ListNode) //建立頭指針,其指針不變 // 123%10=3 // 12.3%10=2 // 1.23%10=1 // 120%10=0 // 12 %10=2 // 1.2%10=1 if nums > 1 || nums%10 > 0 { middle.Val = nums % 10 fmt.Printf("middle.Val: %v\n", middle.Val) if nums > 1 { nums /= 10 middle.Next = RecurCreateList(nums) } } return middle }
鏈表的讀取
遍歷讀取
鏈表讀取時(shí)我們需要根據(jù)是否具有頭節(jié)點(diǎn)進(jìn)行一定的調(diào)整,下面是使用遍歷(迭代)進(jìn)行創(chuàng)建的過(guò)程
// 嘗試遍歷讀取鏈表 func ReadList(L ListNode) { middle := L //將頭節(jié)點(diǎn)賦予這里的中間節(jié)點(diǎn)middle //循環(huán)讀取鏈表的內(nèi)容 for middle.Next != nil { v := middle.Next.Val //由于我們這里判斷的是本身節(jié)點(diǎn)是否為空,所以在輸出時(shí)使用下一節(jié)點(diǎn)的值進(jìn)行輸出,避免錯(cuò)過(guò)某個(gè)值 fmt.Printf("v: %v\n", v) // // fmt.Printf("L: %v\n", L) middle = *middle.Next // // fmt.Printf("L: %v\n", L) } }
遞歸讀取
下面為使用遞歸進(jìn)行讀取的方法
由于節(jié)點(diǎn)的定義過(guò)程中使用內(nèi)嵌,在建立相關(guān)函數(shù)時(shí)都使用指針比較方便[ 雖然前面都沒(méi)注意:( ],
// 嘗試遞歸讀取鏈表 func RecurReadList(L *ListNode) { fmt.Printf("L.Val: %v\n", L.Val) //打印出此節(jié)點(diǎn)中的Val //如果本結(jié)點(diǎn)的指針不為空,即還有下一個(gè)節(jié)點(diǎn),繼續(xù)讀取 if L.Next != nil { RecurReadList(L.Next) //將下個(gè)節(jié)點(diǎn)的指針傳入 } //如果運(yùn)行到這里,說(shuō)明指針為空,函數(shù)也就到此結(jié)束了 }
完整代碼
package main import ( "fmt" ) type ListNode struct { Val int Next *ListNode } func main() { // l := CreateList(13) l := RecurCreateList(13) fmt.Printf("l: %v\n", *l) // ReadList(*l) RecurReadList(l) // RecurReadList(l.Next) // fmt.Println(l.Next.Val) } // 嘗試建立有頭節(jié)點(diǎn)的鏈表,關(guān)鍵在于賦值給middle.next func CreateList(nums int) *ListNode { Head := new(ListNode) //這代表一整個(gè)鏈表,并通過(guò)這里的頭節(jié)點(diǎn)進(jìn)行標(biāo)注,方便該鏈表的引用 middle := Head //middle視作Head鏈表的中間節(jié)點(diǎn),其一直改變 for nums > 0 { middle.Next = &ListNode{Val: nums % 10} //頭節(jié)點(diǎn)賦值方法 fmt.Printf("middle.Val: %v\n", middle.Val) middle = middle.Next nums /= 10 } return Head } // 遞歸建立鏈表 func RecurCreateList(nums int) *ListNode { //在遞歸時(shí)好像不需要單獨(dú)保存頭節(jié)點(diǎn)位置,后續(xù)的位置會(huì)遞歸存儲(chǔ)在next中,不用考慮被覆蓋的問(wèn)題 middle := new(ListNode) //建立頭指針,其指針不變 // 123%10=3 // 12.3%10=2 // 1.23%10=1 // 120%10=0 // 12 %10=2 // 1.2%10=1 if nums > 1 || nums%10 > 0 { middle.Val = nums % 10 fmt.Printf("middle.Val: %v\n", middle.Val) if nums > 1 { nums /= 10 middle.Next = RecurCreateList(nums) } } return middle } // 嘗試遍歷讀取鏈表 func ReadList(L ListNode) { middle := L //將頭節(jié)點(diǎn)賦予這里的中間節(jié)點(diǎn)middle //循環(huán)讀取鏈表的內(nèi)容 for middle.Next != nil { v := middle.Next.Val //由于我們這里判斷的是本身節(jié)點(diǎn)是否為空,所以在輸出時(shí)使用下一節(jié)點(diǎn)的值進(jìn)行輸出,避免錯(cuò)過(guò)某個(gè)值 fmt.Printf("v: %v\n", v) // // fmt.Printf("L: %v\n", L) middle = *middle.Next // // fmt.Printf("L: %v\n", L) } } // 嘗試遞歸讀取鏈表 func RecurReadList(L *ListNode) { fmt.Printf("L.Val: %v\n", L.Val) //打印出此節(jié)點(diǎn)中的Val //如果本結(jié)點(diǎn)的指針不為空,即還有下一個(gè)節(jié)點(diǎn),繼續(xù)讀取 if L.Next != nil { RecurReadList(L.Next) //將下個(gè)節(jié)點(diǎn)的指針傳入 } //如果運(yùn)行到這里,說(shuō)明指針為空,函數(shù)也就到此結(jié)束了 }
到此這篇關(guān)于詳解Golang中鏈表的創(chuàng)建和讀取的文章就介紹到這了,更多相關(guān)Go鏈表內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go語(yǔ)言定時(shí)器Timer和Ticker的使用與區(qū)別
在Go語(yǔ)言中內(nèi)置的有兩個(gè)定時(shí)器,Timer和Ticker,本文主要介紹了Go語(yǔ)言定時(shí)器Timer和Ticker的使用與區(qū)別,具有一定的參考價(jià)值,感興趣的可以了解一下2024-07-07Golang Mutex實(shí)現(xiàn)互斥的具體方法
Mutex是Golang常見(jiàn)的并發(fā)原語(yǔ),在開(kāi)發(fā)過(guò)程中經(jīng)常使用到,本文主要介紹了Golang Mutex實(shí)現(xiàn)互斥的具體方法,具有一定的參考價(jià)值,感興趣的可以了解一下2023-04-04基于Go+OpenCV實(shí)現(xiàn)人臉識(shí)別功能的詳細(xì)示例
OpenCV是一個(gè)強(qiáng)大的計(jì)算機(jī)視覺(jué)庫(kù),提供了豐富的圖像處理和計(jì)算機(jī)視覺(jué)算法,本文將向你介紹在Mac上安裝OpenCV的步驟,并演示如何使用Go的OpenCV綁定庫(kù)進(jìn)行人臉識(shí)別,需要的朋友可以參考下2023-07-07