开发者学堂课程【Go 语言核心编程 - 数据结构和算法: 数据结构和算法-环形链表的删除】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/627/detail/9844
数据结构和算法-环形链表的删除
本节课主要学习,环形链表的删除,代码如下:
现在可以多加几只猫
//创建一只猫
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)
Listcircle Link(head)
}
运行发现三只猫的确是可以的,运行结果如下:
现在要删除一只猫,也就是从环形里边去掉它,现在的情况就是第二只猫指向了第三只猫,第三只猫指向了第一只猫,都是单向的,形成一个环状。现在想删除第二只猫,首先必须要有一个辅助结点在1号上,还要考虑头结点被删除掉了,如果把头结点删掉的话,原先的头结点还要返回一次。
先找 temp,让它指向 head,然后做一个辅助结点 hepler,先让它指到最后的结点,这样做的好处就是让 temp 比较,原先可以做到让 temp 和下一个头结点比较,是因为头结点本来是没有值的,它可以不参与比较,但是现在是头结点本来就有值。
删除一个环形单向链表的思路如下:
1. 先让 temp 指向 head
2. 让 helper 指向环形链表的最后
3. 让 temp 和要删除的id比较,如果相同,则同 helper 完成删除,这里必须考虑如果删除的就是头结点
现在相当于是两个 head 都指向1号,之前的 head 就是要删掉的,不可以用 head 改变里边的值,如果要删除节点本身,一号就没位置了,删除时候要重新返回 head 值,此时代码如下:
//删除一只猫
func DelCatNode (head*CatNode, id int){
//给一只猫的 id
temp:=head
helper:=head
//空链表
if temp. next=nil{
fmt. println("这是一个空的环形链表,不能删除")
return
}
}
要考虑只有一个结点,从理论上来说,只要把 next 置空就可以了。
//如果只有一个结点
if temp. Next==head {
//只有一个结点
temp. next=nil I
return
}
现在开始写第三步
//将 helper 定位到链表最后
For
{
if helper. next==head{
break
}
helper=helper, next;
}
//如果有两个包含两个以上结点,就按刚才的思路来。
Flag:=true
For
{
if temp. next==head {
//如果到这来,说明我比较到最后一个[说明已经找到了,但是最后一个还没比较]已经到最后一个了
Break 现在退出,要是不退出的话就没法比较了,再比较一个就会很复杂,退出再比较。
}
if temp. no=id(
If temp==head {
//说明删除的是头结点
//恭喜找到.,我们也可以在直接删除
Helper.next = temp.next
头结点会发生变化,但是仍然是有效的链表,相当于走了一圈
Fmt.Prinf(“猫猫=%d,id)
Flag=false
break
}
在不停找的过程中,假设一直没有找到,假设 temp 找到 helper,已经找到最后一个结点还没有找到,说明最后那个还没有比较,还得来一次才可以。此时代码如下:
//这里还有比较一次,如果删除过了就不需要再删除了,我们要保证 id 不重复,id 重复就会更复杂。
If flag {
//如果 flag 为真,则上边 for 中没有删除
If temp .no==id
{
Helper.next = temp.next
Fmt.Prinf(“猫猫=%d,id)
}
Else
{
Fmt.println(“对不起,没有 id”)
}
Return
}
//将 helper 定位到链表最后
for{
if helper, next==head{break
helper=helper. next
}
如果删除的是头结点,就会出现 helper 的下一个结点指向2号,头结点还是2号,但是已经不是环形的了,真正的头结点要指向2号
整个流程 temp 都在不停的移动,helper 也在移动,但是这两个移动不同。
temp=temp. next
//移动[比较]
helper=helper. next
//移动[一旦找到要删除的结点 helper]
最后把结点返回去就好。