詳解Golang中鏈表的創(chuàng)建和讀取
鏈表的相關知識
鏈表有時會具有頭節(jié)點,頭節(jié)點的指針指向第一個節(jié)點的地址,其本身的數(shù)據域可以根據自己的選擇進行賦值
接下來我將以將int轉換為鏈表為例進行演示,如果有什么地方可以改進,也希望路過大神能夠指出
鏈表的創(chuàng)建
鏈表的結構定義一般如下,即由本身的數(shù)據和指向下一個節(jié)點的指針構成
type ListNode struct {
Val int
Next *ListNode//不能直接賦值listnode,避免產生嵌套引用
}
鏈表的創(chuàng)建(每個節(jié)點存儲一位數(shù)字),在創(chuàng)建的過程中 我們需要設置中間的可變節(jié)點,不然我們可能會丟失對鏈表的第一個節(jié)點的索引,以下的例子中我們就使用middle為中間節(jié)點;將head設置為頭節(jié)點,并代表完整的鏈表
模擬方式建立
我們利用迭代的方法,只要還存在num,就更新創(chuàng)建一個新的節(jié)點
// 嘗試建立有頭節(jié)點的鏈表,關鍵在于賦值給middle.next
func CreateList(nums int) *ListNode {
Head := new(ListNode) //這代表一整個鏈表,并通過這里的頭節(jié)點進行標注,方便該鏈表的引用
middle := Head //middle視作Head鏈表的中間節(jié)點,其一直改變
for nums > 0 {
middle.Next = &ListNode{Val: nums % 10}//頭節(jié)點賦值方法
fmt.Printf("middle.Val: %v\n", middle.Val)
middle = middle.Next
nums /= 10
}
return Head
}
鏈表的遞歸創(chuàng)建
// 遞歸建立鏈表
func RecurCreateList(nums int) *ListNode {
//在遞歸時好像不需要單獨保存頭節(jié)點位置,后續(xù)的位置會遞歸存儲在next中,不用考慮被覆蓋的問題
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
}
鏈表的讀取
遍歷讀取
鏈表讀取時我們需要根據是否具有頭節(jié)點進行一定的調整,下面是使用遍歷(迭代)進行創(chuàng)建的過程
// 嘗試遍歷讀取鏈表
func ReadList(L ListNode) {
middle := L //將頭節(jié)點賦予這里的中間節(jié)點middle
//循環(huán)讀取鏈表的內容
for middle.Next != nil {
v := middle.Next.Val //由于我們這里判斷的是本身節(jié)點是否為空,所以在輸出時使用下一節(jié)點的值進行輸出,避免錯過某個值
fmt.Printf("v: %v\n", v)
// // fmt.Printf("L: %v\n", L)
middle = *middle.Next
// // fmt.Printf("L: %v\n", L)
}
}
遞歸讀取
下面為使用遞歸進行讀取的方法
由于節(jié)點的定義過程中使用內嵌,在建立相關函數(shù)時都使用指針比較方便[ 雖然前面都沒注意:( ],
// 嘗試遞歸讀取鏈表
func RecurReadList(L *ListNode) {
fmt.Printf("L.Val: %v\n", L.Val) //打印出此節(jié)點中的Val
//如果本結點的指針不為空,即還有下一個節(jié)點,繼續(xù)讀取
if L.Next != nil {
RecurReadList(L.Next) //將下個節(jié)點的指針傳入
}
//如果運行到這里,說明指針為空,函數(shù)也就到此結束了
}完整代碼
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é)點的鏈表,關鍵在于賦值給middle.next
func CreateList(nums int) *ListNode {
Head := new(ListNode) //這代表一整個鏈表,并通過這里的頭節(jié)點進行標注,方便該鏈表的引用
middle := Head //middle視作Head鏈表的中間節(jié)點,其一直改變
for nums > 0 {
middle.Next = &ListNode{Val: nums % 10} //頭節(jié)點賦值方法
fmt.Printf("middle.Val: %v\n", middle.Val)
middle = middle.Next
nums /= 10
}
return Head
}
// 遞歸建立鏈表
func RecurCreateList(nums int) *ListNode {
//在遞歸時好像不需要單獨保存頭節(jié)點位置,后續(xù)的位置會遞歸存儲在next中,不用考慮被覆蓋的問題
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é)點賦予這里的中間節(jié)點middle
//循環(huán)讀取鏈表的內容
for middle.Next != nil {
v := middle.Next.Val //由于我們這里判斷的是本身節(jié)點是否為空,所以在輸出時使用下一節(jié)點的值進行輸出,避免錯過某個值
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é)點中的Val
//如果本結點的指針不為空,即還有下一個節(jié)點,繼續(xù)讀取
if L.Next != nil {
RecurReadList(L.Next) //將下個節(jié)點的指針傳入
}
//如果運行到這里,說明指針為空,函數(shù)也就到此結束了
}
到此這篇關于詳解Golang中鏈表的創(chuàng)建和讀取的文章就介紹到這了,更多相關Go鏈表內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于Go+OpenCV實現(xiàn)人臉識別功能的詳細示例
OpenCV是一個強大的計算機視覺庫,提供了豐富的圖像處理和計算機視覺算法,本文將向你介紹在Mac上安裝OpenCV的步驟,并演示如何使用Go的OpenCV綁定庫進行人臉識別,需要的朋友可以參考下2023-07-07

