一:鏈表介紹
鏈表是有序的列表,但在內存的分部較為特殊
二:單鏈表的舉例使用
package main
import (
"fmt"
)
type Students struct{
num int
name string
next *Students
}
//尾部添加
func InsertStudentNode1(head *Students, student *Students){
//設置從頭部開始遍歷
temp := head
for {
if temp.next == nil {
break
}
temp = temp.next
}
temp.next=student
}
//有序添加
func InsertStudentNode2(head *Students, student *Students){
temp := head
for {
if temp.next == nil {
break
}else if temp.next.num > student.num {//按照有小到大添加
break
}else if temp.next.num == student.num {
fmt.Println("節點已存在")
return
}
temp = temp.next
}
student.next = temp.next
temp.next = student
}
//顯示所有節點
func ShowStudentNode(head *Students){
//設置從頭部開始遍歷
show := head
//先判斷是否為空鏈表
if show.next == nil {
fmt.Println("鏈表為空")
return
}
for {
if show.next == nil {
break
}
fmt.Printf("學生編號:%v,姓名:%v\n", show.next.num, show.next.name)
show = show.next
}
}
//刪除節點
func DelStudentNode(head *Students, num int){
temp := head
if temp.next == nil {
fmt.Println("鏈表為空")
return
}
for {
if temp.next.num == num {
break
}else if temp.next == nil {
fmt.Println("節點不存在")
return
}
temp = temp.next
}
temp.next = temp.next.next
}
func main() {
//初始化一個頭結點
head := &Students{}
//添加新節點
student1 := &Students{
num : 1,
name : "james",
}
student2 := &Students{
num : 2,
name : "kobe",
}
student5 := &Students{
num : 5,
name : "jorden",
}
student3 := &Students{
num : 3,
name : "shark",
}
// 添加節點
InsertStudentNode1(head, student1)
InsertStudentNode1(head, student2)
InsertStudentNode1(head, student5)
InsertStudentNode2(head, student3)
//獲取
ShowStudentNode(head)
//刪除編號為5的學生
DelStudentNode(head, 1)
fmt.Println("刪除后----------------")
//獲取
ShowStudentNode(head)
} 結果 [ `go run chainTable.go` | done ]
學生編號:1,姓名:james
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:5,姓名:jorden
刪除后----------------
學生編號:2,姓名:kobe
學生編號:3,姓名:shark
學生編號:5,姓名:jorden
三:雙向鏈表
①:雙線鏈表的優點
①-1:單向鏈表的查找方向只能向后查找,而雙線鏈表可以向后也可以向前;
①-2:單向鏈表不能自我刪除,需要其他節點的協助,而雙線鏈表可以自我刪除(根據指向的前節點與指向的后節點)
②:舉例說明
package main import ( "fmt" ) type Students struct{ num int name string pre *Students next *Students } //尾部添加 func InsertStudentNode1(head *Students, student *Students){ //設置從頭部開始遍歷 temp := head for { if temp.next == nil { break } temp = temp.next } temp.next=student student.pre = temp } //有序添加 func InsertStudentNode2(head *Students, student *Students){ temp := head last := false for { if temp.next == nil { last = true break }else if temp.next.num > student.num {//按照有小到大添加 break }else if temp.next.num == student.num { fmt.Println("節點已存在") return } temp = temp.next } if last { temp.next = student student.pre = temp }else{ student.next = temp.next temp.next = student student.next.pre = student student.pre = temp } } //顯示所有節點 func ShowStudentNode(head *Students){ //設置從頭部開始遍歷 show := head //先判斷是否為空鏈表 if show.next == nil { fmt.Println("鏈表為空") return } for { if show.next == nil { fmt.Println("最后節點的前一個節點信息") fmt.Printf("學生編號:%v,姓名:%v\n", show.pre.num, show.pre.name) return } fmt.Printf("學生編號:%v,姓名:%v\n", show.next.num, show.next.name) show = show.next } } //刪除節點 func DelStudentNode(head *Students, num int){ temp := head if temp.next == nil { fmt.Println("鏈表為空") return } //用於判斷是否為最后一個節點 last := false for { if temp.next.num == num { //再判斷一下是否為最后一個節點 if temp.next.next == nil { last = true } break }else if temp.next == nil { fmt.Println("節點不存在") return } temp = temp.next } if last { temp.next = nil }else{ temp.next = temp.next.next temp.next.pre = temp } } func main() { //初始化一個頭結點 head := &Students{} //添加新節點 student1 := &Students{ num : 1, name : "james", } student2 := &Students{ num : 2, name : "kobe", } student5 := &Students{ num : 5, name : "jorden", } student3 := &Students{ num : 3, name : "shark", } // 添加節點 InsertStudentNode1(head, student1) InsertStudentNode1(head, student2) InsertStudentNode1(head, student5) InsertStudentNode2(head, student3) //獲取 ShowStudentNode(head) //刪除編號為5的學生 DelStudentNode(head, 1) fmt.Println("刪除后----------------") //獲取 ShowStudentNode(head) } 結果 [ `go run doubleChainTable.go` | done ] 學生編號:1,姓名:james 學生編號:2,姓名:kobe 學生編號:3,姓名:shark 學生編號:5,姓名:jorden 最后節點的前一個節點信息 學生編號:3,姓名:shark 刪除后---------------- 學生編號:2,姓名:kobe 學生編號:3,姓名:shark 學生編號:5,姓名:jorden 最后節點的前一個節點信息 學生編號:3,姓名:shark
四:環形單向鏈表
①:介紹,參考環形數組隊列
②:環形單向鏈表與單向鏈表和雙向鏈表不同之處在於,head也要存放數據
③:使用舉例
package main import ( "fmt" ) type Students struct{ num int name string next *Students } //尾部添加 func InsertStudentNode1(head *Students, student *Students){ temp := head //先判斷頭部是否為空 if temp.next == nil { temp.num = student.num temp.name = student.name //自環 temp.next = temp return } for { if temp.next == head { break } temp = temp.next } student.next = head temp.next=student } //顯示所有節點 func ShowStudentNode(head *Students){ //設置從頭部開始遍歷 show := head //先判斷是否為空鏈表 if show.next == nil { fmt.Println("鏈表為空") return } for { fmt.Printf("學生編號:%v,姓名:%v\n", show.num, show.name) if show.next == head { break } show = show.next } } //刪除節點 func DelStudentNode(head *Students, num int) *Students{ temp := head helper := head//幫助節點跳過將要刪除的節點 if temp.next == nil { fmt.Println("鏈表為空") return head } //判斷是否只有一個節點 if temp.next == head { if temp.num == num { temp.next = nil }else{ fmt.Println("節點不存着") } return head } //將helper定位到最后一個節點 for { if helper.next == head{ break } helper = helper.next } //當節點有多個時 flag := true for{ if temp.next == head{ break } if temp.num == num { if temp == head{//判斷是否刪除頭節點 head = head.next } helper.next = temp.next fmt.Println("num=",num) flag = false break } temp = temp.next helper = helper.next } if flag { if temp.num == num { //說明要刪除的節點是最后一個,這時temp已經指向最后一個節點 helper.next = temp.next }else{ fmt.Println("節點不存在") } } //防止要刪除的節點是頭部,返回最新的頭部位置 return head } func main() { //初始化一個頭結點 head := &Students{} //添加新節點 student1 := &Students{ num : 1, name : "james", } student2 := &Students{ num : 2, name : "kobe", } student3 := &Students{ num : 3, name : "shark", } student4 := &Students{ num : 4, name : "shark", } // 添加節點 InsertStudentNode1(head, student1) InsertStudentNode1(head, student2) InsertStudentNode1(head, student3) InsertStudentNode1(head, student4) // 獲取 ShowStudentNode(head) //刪除編號為5的學生 head = DelStudentNode(head, 1) fmt.Println("刪除后----------------") //獲取 ShowStudentNode(head) } 結果 [ `go run circleChainTable.go` | done ] 學生編號:1,姓名:james 學生編號:2,姓名:kobe 學生編號:3,姓名:shark 學生編號:4,姓名:shark num= 1 刪除后---------------- 學生編號:2,姓名:kobe 學生編號:3,姓名:shark 學生編號:4,姓名:shark