Golang双向链表
package main
import "fmt"
type HeroNode struct {
No int
Name string
NickName string
Prev *HeroNode
Next *HeroNode
}
// 插入一个新结点
func InsetHeroNode(head *HeroNode, newHeroNode *HeroNode) {
// 1.先找到该链表的最后这个结点
// 2.创建一个辅助结点[跑龙套, 帮忙]
temp := head
for {
if temp.Next == nil {
break
}
temp = temp.Next
}
// 3.将newHeroNode加入到链表的最后
newHeroNode.Prev = temp
temp.Next = newHeroNode
}
// 根据no的编号从小到大插入..
func InsetHeroNodeBySort(head *HeroNode, newHeroNode *HeroNode) {
// 1.先找到该链表的最后这个结点
// 2.创建一个辅助结点[跑龙套, 帮忙]
temp := head
flag := true
for {
// 说明该链表为空或者到最后
if temp.Next == nil {
break
}
// 说明newHeroNode就应该插入到temp后面
if temp.Next.No > newHeroNode.No {
break
}
// 说明这个链表中货已经存在了该no
if temp.Next.No == newHeroNode.No {
flag = false
break
}
// 漂移链表位置
temp = temp.Next
}
if !flag {
fmt.Println("已经存在no=", newHeroNode.No)
return
}
// 插入链表
newHeroNode.Next = temp.Next
newHeroNode.Prev = temp
// 判断 newHeroNode 是不是加载末尾
if temp.Next != nil {
temp.Next.Prev = newHeroNode
}
temp.Next = newHeroNode
}
// 删除一个结点
func DelHeroNode(head *HeroNode, no int) {
// 1.创建一个辅助结点[跑龙套, 帮忙]
temp := head
// 2.找到要删除结点的no, 和temp的下一个结点的no比较
flag := false
for {
// 说明到链表的最后
if temp.Next == nil {
break
}
if temp.Next.No == no {
flag = true
break
}
// 漂移到下一个结点
temp = temp.Next
}
if !flag {
fmt.Printf("删除的no不存在\n")
return
}
// 重新指向
temp.Next = temp.Next.Next
// 判断 temp.Next 是不是链表尾部
if temp.Next != nil {
temp.Next.Prev = temp
}
}
//显示链表的所有结点信息<从前往后>
func ListHeroNode(head *HeroNode) {
// 1.创建一个辅助结点[跑龙套, 帮忙]
temp := head
// 先判断该链表是不是一个空的链表
if temp.Next == nil {
fmt.Println("heroNode empty")
return
}
// 2.遍历链表
fmt.Printf("\t从前往后: ")
for {
fmt.Printf("[%d, %s, %s]-->", temp.Next.No, temp.Next.Name, temp.Next.NickName)
temp = temp.Next
if temp.Next == nil {
break
}
}
fmt.Println()
}
//显示链表的所有结点信息<从后往前>
func ListHeroNodeBySort(head *HeroNode) {
// 1.创建一个辅助结点[跑龙套, 帮忙]
temp := head
// 先判断该链表是不是一个空的链表
if temp.Next == nil {
fmt.Println("heroNode empty")
return
}
//2. 让temp定位到双向链表的最后结点
for {
if temp.Next == nil {
break
}
temp = temp.Next
}
// 3.遍历链表
fmt.Printf("\t从后往前: ")
for {
fmt.Printf("[%d, %s, %s]-->", temp.No, temp.Name, temp.NickName)
temp = temp.Prev
if temp.Prev == nil {
break
}
}
fmt.Println()
}
func main() {
// 1.县创建一个头结点
head := &HeroNode{}
//2. 创建一个新的HeroNode
hero1 := &HeroNode{No: 1, Name: "宋江", NickName: "及时雨"}
hero3 := &HeroNode{No: 3, Name: "林冲", NickName: "豹子头"}
hero2 := &HeroNode{No: 2, Name: "卢俊义", NickName: "玉麒麟"}
//// 3.无序插入
//fmt.Println("无序插入:")
//InsetHeroNode(head, hero2)
//InsetHeroNode(head, hero1)
//InsetHeroNode(head, hero3)
//ListHeroNode(head)
// 4.按从小到大插入
fmt.Println("按从小到大插入:")
InsetHeroNodeBySort(head, hero2)
InsetHeroNodeBySort(head, hero1)
InsetHeroNodeBySort(head, hero3)
ListHeroNode(head)
ListHeroNodeBySort(head)
// 5.删除
fmt.Println("删除-> no = 1: ")
DelHeroNode(head, 1)
ListHeroNode(head)
ListHeroNodeBySort(head)
fmt.Println("删除-> no = 2: ")
DelHeroNode(head, 2)
ListHeroNode(head)
ListHeroNodeBySort(head)
fmt.Println("删除-> no = 3: ")
DelHeroNode(head, 3)
ListHeroNodeBySort(head)
ListHeroNode(head)
ListHeroNodeBySort(head)
fmt.Println("删除-> no = 4:")
DelHeroNode(head, 4)
}