//单向链表的缺点分析
//1、单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找
//2、单向链表不能自我删除,需要靠辅助节点,而双向链表可以自我删除。
//双向链表的实现
//一、双向链表的添加、显示和删除
package main
import "fmt"
//一、双向链表的添加、显示和删除
//定义一个HeroNode
type HeroNode struct {
no int
name string
nickname string
pre *HeroNode // 表示指向前一个结点
next *HeroNode // 表示指向下一个结点
}
//一、编写第1种插入方法
func InsertHeroNode(head *HeroNode, newHeroNode *HeroNode) {
//1、创建一个辅助结点
temp := head
//2、先找到该链表的最后这个结点
for {
if temp.next == nil { //表示到链表最后
break
}
temp = temp.next // 让temp不断指向下一个结点
}
//3、将newHeroNode加入到链表最后
temp.next = newHeroNode
newHeroNode.pre = temp
}
//二、编写第2种插入方法,有序插入
func InsertHeroNode2(head *HeroNode, newHeroNode *HeroNode) {
//1、创建一个辅助结点
temp := head
flag := true
//2、先找到适当的结点
//让插入的结点no,和temp的下一个结点的no进行比较
for {
if temp.next == nil {
break
} else if temp.next.no > newHeroNode.no { //说明newHeroNode 应该插入temp后面
break
} else if temp.next.no == newHeroNode.no {
//说明已经存在这个no
flag = false
break
}
temp = temp.next
}
if !flag {
fmt.Println("对不起,已经存在no=", newHeroNode.no)
return
} else {
newHeroNode.next = temp.next
newHeroNode.pre = temp
if temp.next != nil {
temp.next.pre = newHeroNode
}
temp.next = newHeroNode
}
}
//删除一个结点
func DelHeroNode(head *HeroNode, id int) {
temp := head
flag := false
//找到要删除的结点no,和temp的下一个结点的no进行比较
for {
if temp.next == nil {
break
} else if temp.next.no == id {
//说明已经找到
flag = true
break
}
temp = temp.next
}
if flag { //找到,删除
temp.next = temp.next.next
if temp.next != nil {
temp.next.pre = temp
}
} else {
fmt.Println("你要删除的id不存在")
}
}
//显示链表的所有结点信息
//为了证明是双向链表,现在逆向打印
func ListHeroNode(head *HeroNode) {
//1、创建一个辅助结点
temp := head
//2、判断该链表是不是一个空的链表
if temp.next == nil {
fmt.Println("空空如也")
return
}
//让temp定位到双向链表的最后结点
for {
if temp.next == nil {
break
}
temp = temp.next
}
//3、遍历这个链表
for {
fmt.Printf("[%d, %s, %s]->", temp.no, temp.name, temp.nickname)
temp = temp.pre
//判断是否链表头
if temp.pre == nil {
break
}
}
}