詳解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?sync.Once實(shí)現(xiàn)高效單例模式詳解
這篇文章主要為大家介紹了go?sync.Once實(shí)現(xiàn)高效單例模式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
golang gorm 計(jì)算字段和獲取sum()值的實(shí)現(xiàn)
這篇文章主要介紹了golang gorm 計(jì)算字段和獲取sum()值的實(shí)現(xiàn)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
go-micro微服務(wù)JWT跨域認(rèn)證問(wèn)題
JWT 以 JSON 對(duì)象的形式安全傳遞信息。因?yàn)榇嬖跀?shù)字簽名,因此所傳遞的信息是安全的,這篇文章主要介紹了go-micro微服務(wù)JWT跨域認(rèn)證,需要的朋友可以參考下2023-01-01
Go實(shí)現(xiàn)整合Logrus實(shí)現(xiàn)日志打印
這篇文章主要介紹了Go實(shí)現(xiàn)整合Logrus實(shí)現(xiàn)日志打印,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07
golang中兩個(gè)協(xié)程交替打印數(shù)字和字母的實(shí)現(xiàn)
這篇文章給大家介紹了golang中兩個(gè)協(xié)程交替打印數(shù)字和字母的實(shí)現(xiàn),文中通過(guò)代碼示例講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-01-01
基于Go語(yǔ)言開(kāi)發(fā)篇一個(gè)命令行進(jìn)程監(jiān)控工具
在生產(chǎn)和開(kāi)發(fā)環(huán)境中,監(jiān)控關(guān)鍵進(jìn)程的存活與資源使用是非常常見(jiàn)的需求,本篇將開(kāi)發(fā)一個(gè)輕量級(jí)的命令行進(jìn)程監(jiān)控工具,感興趣的小伙伴可以了解下2025-09-09

