Go语言实现单链表的增删改查等18种操作

这篇博客介绍了链表的基础操作,包括链表节点的定义、链表的创建、插入、删除、查找、反转和判断是否有环等。此外,还展示了如何在两个已排序链表中合并它们,并提供了具体的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package main

import (
	"fmt"
)

// ListNode 定义为一个链表的节点
type ListNode struct {
	value interface{}
	next  *ListNode
}

// LinkedList 定义为链表
type LinkedList struct {
	head   *ListNode
	length uint
}

// NewListNode 实现了新建一个节点操作
func NewListNode(v interface{}) *ListNode {
	return &ListNode{v, nil}
}

// GetNext 实现了获取节点下一个节点的操作
func (this *ListNode) GetNext() *ListNode {
	return this.next

}

// GetValue 实现了获取结点值的操作
func (this *ListNode) GetValue() interface{} {
	return this.value
}

// NewLinkedList 实现了创建链表的操作
func NewLinkedList() *LinkedList {
	return &LinkedList{NewListNode(0), 0}
}

// InsertAfter 在某个节点后面插入新的节点
func (this *LinkedList) InsertAfter(p *ListNode, v interface{}) bool {
	if p == nil {
		return false
	}
	newNode := NewListNode(v)
	oldNext := p.next
	p.next = newNode
	newNode.next = oldNext
	this.length++
	return true
}

// InsertBefore 实现在某节点前面插入某值
func (this *LinkedList) InsertBefore(p *ListNode, v interface{}) bool {
	if p == nil || p == this.head {
		return false
	}

	cur := this.head.next
	pre := this.head
	for nil != cur { //这里如果遍历完,是指向nil
		if cur == p {
			break
		}
		pre = cur
		cur = cur.next
	}

	if cur == nil { //这里要判断一下是防止p为链表不存在的节点,那么cur会指向结尾的nil
		return false
	}
	newNode := NewListNode(v)
	pre.next = newNode
	newNode.next = cur
	this.length++
	return true
}

// InsertToHead 实现在表头插入元素的操作
func (this *LinkedList) InsertToHead(v interface{}) bool {
	return this.InsertAfter(this.head, v)
}

// InsertToTail 实现在链表尾部插入的操作
func (this *LinkedList) InsertToTail(v interface{}) bool {
	cur := this.head
	for nil != cur.next { //这里cur最后要指向最后一个节点
		cur = cur.next
	}
	return this.InsertAfter(cur, v)
}

// FindByIndex 实现通过索引查找节点操作
func (this *LinkedList) FindByIndex(index uint) *ListNode {
	if index >= this.length {
		return nil
	}

	cur := this.head.next
	var i uint = 0
	for ; i < index; i++ {
		cur = cur.next
	}
	return cur
}

// DeletNode 删除传入的节点
func (this *LinkedList) DeletNode(p *ListNode) bool {
	if p == nil {
		return false
	}

	cur := this.head.next
	pre := this.head
	for nil != cur {
		if cur == p {
			break
		}
		pre = cur
		cur = cur.next
	}

	if cur == nil {
		return false
	}
	pre.next = cur.next
	p = nil
	this.length--
	return true

}

//实现打印列表
func (this *LinkedList) Print() {
	cur := this.head.next
	format := ""
	for nil != cur {
		format += fmt.Sprintf("%v", cur.GetValue())
		if cur.next != nil {
			format += "->"
		}
		cur = cur.next
	}
	fmt.Println(format)
}

// Reverse 实现单链表的反转
func (this *LinkedList) Reverse() {
	if this.head == nil || this.head.next == nil || this.head.next.next == nil {
		return
	}

	var pre *ListNode = nil
	var cur *ListNode = this.head.next
	var next *ListNode = nil

	for nil != cur {
		next = cur.next
		cur.next = pre
		pre = cur
		cur = next
	}

	this.head.next = pre

}

// HasCycle 实现判断单链表是否有环的操作
//计算环长:两次相遇之间的节点个数(注意头节点不计,第一次相遇点和第二次相遇点只能记录其中一个)
//单链表长度:从开始就记录slow经过的点,两次相遇后(头节点和最后一个相遇点不计),总点数-环长+1
func (this *LinkedList) HasCycle() bool {
	if nil != this.head {
		slow := this.head
		fast := this.head
		for nil != fast && nil != fast.next {
			slow = slow.next
			fast = fast.next.next
			if slow == fast {
				return true
			}
		}
	}
	return false
}

// DeleteBottom 删除倒数第N个节点
func (this *LinkedList) DeleteBottom(n int) {
	if n <= 0 || nil == this.head || nil == this.head.next {
		return
	}
	fast := this.head
	for i := 1; i <= n && nil != fast; i++ {
		fast = fast.next
	}
	if nil == fast {
		return
	}

	slow := this.head

	for nil != fast.next {
		slow = slow.next
		fast = fast.next
	}

	slow.next = slow.next.next

}

// FindMiddleNode 获取中间节点
func (this *LinkedList) FindMiddleNode() *ListNode {
	if nil == this.head || nil == this.head.next {
		return nil
	}

	if nil == this.head.next.next {
		return this.head.next
	}

	slow, fast := this.head, this.head

	for nil != fast || nil != fast.next {
		slow = slow.next
		fast = fast.next
	}

	return slow

}

//实现两个有序链表合并

func MergeSortedlist(l1, l2 *LinkedList) *LinkedList {
	//若l1为空则返回l2
	if nil == l1.head || nil == l2.head.next {
		return l2
	}

	//若l2为空,则返回l1
	if nil == l2.head || nil == l2.head.next {
		return l1
	}

	l := &LinkedList{&ListNode{0, nil}, 0}
	cur := l.head
	cur1 := l1.head.next
	cur2 := l2.head.next

	for nil != cur1 && nil != cur2 {
		if cur1.value.(int) >= cur2.value.(int) {
			cur.next = cur2
			cur = cur.next
			cur2 = cur2.next
		} else {
			cur.next = cur1
			cur = cur.next
			cur1 = cur1.next
		}
	}

	if nil != cur1 {
		cur.next = cur1
	}

	if nil != cur2 {
		cur.next = cur2
	}
	return l
}

func main() {
	list := NewLinkedList()
	list.InsertToTail(2)
	list.InsertToHead(1)
	list.InsertToTail(3)
	list.InsertToTail(4)
	list.Print()
	//list.Reverse()
	list.Print()
	fmt.Println(list.HasCycle())

	list1 := NewLinkedList()
	list1.InsertToTail(2)
	list1.InsertToTail(4)
	list1.InsertToTail(7)
	list1.InsertToTail(10)
	list1.Print()
	MergeSortedlist(list, list1).Print()
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值