一、分析单向环形列表如何完成遍历,添加,修改和删除的思路
- 环形列表的一个重要特质就是首尾相连,如果只有headNode节点则next指向自己。
- 添加:如果有新节点则当前节点的next指向新节点,新节点的next指向headNode节点
- 修改:找到编号和新节点编号相同的节点,将新节点的next指向上一个节点的next节点的next节点,然后上一个节点的next指向新节点。
-
删除:
1、如果点删除的节点是头结点,则next设为nil
2、如果循环到倒数第一个节点还没有找到则需要跳出循环,点单独处理这个节点,防止死循环。
3、如果多个节点删除的是头结点需要将头结点让位给下一个节点。 -
展示:从头结点开始遍历,知道当前节点的next节点是headNode节点就终止。
二、代码展示
package main
import (
"fmt"
)
//定义猫的结构体结点
type CatNode struct {
no int //猫猫的编号
name string
next *CatNode
}
//添加
func InsertCatNode(head *CatNode, newCatNode *CatNode) {
if head.next == nil {
head.no = newCatNode.no
head.name = newCatNode.name
head.next = head
}
temp := head
for {
if temp.next == head {
break
}
temp = temp.next
}
temp.next = newCatNode
newCatNode.next = head
}
//修改
func UpdateCatNode(head *CatNode, newCatNode *CatNode) {
temp := head
for {
if temp.next.no == newCatNode.no {
break
}
temp = temp.next
}
newCatNode.next = temp.next.next
temp.next = newCatNode
}
//输出这个环形的链表
func ListCircleLink(head *CatNode) {
temp := head
if head.next == nil {
fmt.Println("没有数据")
}
for {
fmt.Printf("猫的信息为=[id=%d name=%s] ->\n", temp.no, temp.name)
if temp.next == head {
break
}
temp = temp.next
}
}
//删除
func DelCatNode(head *CatNode, id int) *CatNode {
temp := head //负责找
helper := head //负责删除,修改地址
//判断是否为空
if temp.next == nil {
return head //没有数据
}
//注意点1、如果只有一个节点,需要判断是否删除自身
if temp.next == head {
if temp.no == id {
head.next = nil //删除本身
}
return head //说明没有要删除id直接返回
}
//将helper节点指向最后,用来操作内存地址的
for {
if helper.next == head { //倒数第一个
break
}
helper = helper.next
}
//如果有两个包含两个以上结点
flag := true
for {
//注意点2、防止死循环
if temp.next == head { //如果到这来,说明我比较到最后一个【最后一个还没比较】
break
}
if temp.no == id {
//注意点3、如果删除的是头结点需要将头结点让位给下一个节点
if temp == head { //说明删除的是头结点
head = head.next //将头结点的位置传给下一个节点代替,一个环形列表不能没有头
}
//删除处理
helper.next = temp.next
//flag = false
break
}
temp = temp.next
helper = helper.next
}
//这里还有比较一次
if flag { //如果 flag 为真,则我们上面没有删除
if temp.no == id {
helper.next = temp.next
fmt.Printf("猫猫=%d\n", id)
}else {
fmt.Printf("对不起,没有 no=%d\n", id)
}
}
return head
}
func main() {
//这里我们初始化一个环形链表的头结点
head := &CatNode{}
//创建一只猫
cat1 := &CatNode{
no : 1, name : "tom", }
cat2 := &CatNode{
no : 2, name : "tom2", }
cat3 := &CatNode{
no : 3, name : "tom3", }
InsertCatNode(head, cat1)
InsertCatNode(head, cat2)
InsertCatNode(head, cat3)
cat4 := &CatNode{
no : 1, name : "tom1修改", }
UpdateCatNode(head, cat4)
ListCircleLink(head)
head = DelCatNode(head, 4)
fmt.Println()
fmt.Println()
fmt.Println()
ListCircleLink(head)
}