单链表,反转,删除操作

反转

假设链表中元素为 1->2->3->4->5->6->7
我们假设有head:指向旧链表头节点,prev:指向新链表的头节点,next:指向旧链表的头节点的下一个节点 三个变量。
反转链表的步骤:

  • next = head.Next,先记录旧链表的head,和旧链表头部的下一个节点next
  • head.Next = prev,让head.Next 指向prev,由于prev创建时是空,所以在第一轮操作时head.Next指向了空,该操作的目的是让prev这个新链表挂在head的后边
  • prev = head,让prev 指向 head。该操作的目的是让prev 指向 head,从而完成链表的接替。
  • head = next,让head指向next,head 节点指向了head后的节点
  • 重复以上操作,直到head为空
	var prev, next *Node
	for head != nil {
		next = head.Next // 记录下一个节点
		head.Next = prev // 将当前节点 添加到prev 头部
		prev = head      // prev 指向头部
		head = next      // 当前节点指向下一个节点
	}
	return prev

删除

假设链表中元素为 1->2->3->4->5->6->7
假设删除元素1。因为元素1位于链表头部,直接删了他,链表头之后的节点就失去引用了。所以,要进行换头操作:

	for head != nil {
		if head.Value != val {
			break
		}
		head = head.Next
	}

确保链表头是一个不被删除的元素,才能查找链表后续是否还有需要被删除的元素。

在链表的后续节点中检查并删除值

	prev, cur := head, head
	for cur != nil {
		if cur.Value == val {
			prev.Next = cur.Next
		} else {
			prev = cur
		}
		cur = cur.Next
	}

分别记录上一个节点和当前节点,在第一轮时,当前节点和上一个节点一致,所以这一轮只将当前节点指向其next节点的操作是有效的。
如果当前节点的值等于要删除的值,则将上一个节点的next指针赋值当前节点的next指针。也就是让当前节点不再被引用。会在适当的时机被GC掉。
删除头节点,需要重新返回新的链表

完整源码

package main

import (
	"fmt"
)

type Node struct {
	Value int
	Next  *Node
}

func NewList(v ...int) *Node {
	if len(v) <= 0 {
		return nil
	}
	head := &Node{Value: v[0]}
	p := head
	for i := 1; i < len(v); i++ {
		p.Next = &Node{Value: v[i]}
		p = p.Next
	}
	return head
}

func (n *Node) Print() {
	p := n
	for p != nil {
		fmt.Print(p.Value, " -> ")
		p = p.Next
	}
	fmt.Println()
}

func ReverseLinkedList(head *Node) *Node {
	var prev, next *Node
	for head != nil {
		next = head.Next // 记录下一个节点
		head.Next = prev // 将当前节点 添加到prev 头部
		prev = head      // prev 指向头部
		head = next      // 当前节点指向下一个节点
	}
	return prev
}

func RemoveNodeValue(head *Node, val int) *Node {
	// 先检查头节点
	for head != nil {
		if head.Value != val {
			break
		}
		head = head.Next
	}

	prev, cur := head, head
	for cur != nil {
		if cur.Value == val {
			prev.Next = cur.Next
		} else {
			prev = cur
		}
		cur = cur.Next
	}
	return head
}

测试

func main() {
	list := NewList(1, 2, 3, 4, 5, 6, 7)
	list.Print()
	linkedList := ReverseLinkedList(list)
	linkedList.Print()

	linkedList = RemoveNodeValue(linkedList, 2)
	linkedList.Print()
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

metabit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值