单链表及双向链表的代码实现-golang

单链表

package linkedList
// 单链表的实现
type ListNode struct {
Val int
Next *ListNode
}
type MyLinkedList struct {
size int
head *ListNode
}
/*
// initialize struct
func Constructor() MyLinkedList {
return MyLinkedList{0, &ListNode{}}
}
*/
func (this *MyLinkedList) Get(index int) int {
// 通过索引获取链表节点的值
if index < 0 || index >= this.size {
return -1
}
// 通过前继节点获取
prev := this.head
for i:=0;i<index;i++ {
prev = prev.Next
}
return prev.Next.Val
}
func (this *MyLinkedList) AddAtIndex(index int, val int) {
// 通过索引插入节点, 先遍历找到前继节点
if index < 0 || index > this.size {
return
}
// 找到前继节点
prev := this.head
for i:=0;i<index;i++ {
prev = prev.Next
}
// 根据给定val生成新节点
node := &ListNode{Val: val}
// 防止丢失节点,显然新节点指向prev的下个节点
node.Next = prev.Next
// prev指向新节点
prev.Next = node
// 更新size
this.size++
}
func (this *MyLinkedList) AddAtHead(val int) {
// 头部插入新节点
this.AddAtIndex(0, val)
}
func (this *MyLinkedList) AddAtTail(val int) {
// 尾部插入新节点
this.AddAtIndex(this.size, val)
}
func (this *MyLinkedList) DeleteAtIndex(index int) {
// 通过索引删除节点, 依然通过前继节点操作,直接指向下下个节点即可
if index < 0 || index >= this.size {
return
}
// 遍历找到前继节点
prev := this.head
for i:=0;i<index;i++ {
prev = prev.Next
}
// 前继指向下下个节点
prev.Next = prev.Next.Next
// 更新size
this.size--
}

双向链表

//+build ignore
package main
import "fmt"
func main() {
head := ConstrutorD()
head.AddAtHead(2)
head.AddAtHead(5)
head.AddAtHead(7)
head.AddAtIndex(3,4)
head.AddAtTail(100)
head.DeleteAtIndex(3)
fmt.Println(head.Get(0))
fmt.Println(head.Get(1))
fmt.Println(head.Get(2))
fmt.Println(head.Get(3))
}
// 双向链表的实现
type Node struct {
Val int
Prev, Next *Node
}
type MyLinkedListD struct {
size int
head, tail *Node
}
// initialize struct
func ConstrutorD() MyLinkedListD {
return MyLinkedListD{}
}
func (this *MyLinkedListD) Get(index int) int {
// 双向链表,根据索引获取值
if this.size == 0 || index < 0 || index >= this.size {
return -1
}
// 处理头尾节点,fast-way
if index == 0 {
return this.head.Val
}
if index == this.size - 1 {
return this.tail.Val
}
// 从头部遍历到index节点
cur := this.head
count := 0
for cur != nil {
if count == index {
break
}
count++
cur = cur.Next
}
return cur.Val
}
func (this *MyLinkedListD) AddAtIndex(index int, val int) {
// 通过索引插入节点
if index > this.size {
return
}
// 小于0,头部插入
if index <= 0 {
this.AddAtHead(val)
return
}
// 尾部插入
if index == this.size {
this.AddAtTail(val)
return
}
// 一般情况, 找到index节点
cur := this.head
count := 0
for cur != nil && count < index {
count++
cur = cur.Next
}
// 生成新节点, 后继节点为cur, 前继节点为cur的前继节点,
// 相当于 cur.prev<---node--->cur
node := &Node{Val: val, Next: cur, Prev: cur.Prev}
cur.Prev.Next = node // cur的前继节点的下个节点指向新节点, --->
cur.Prev = node // cur的prev指针指向node, <---
// 更新size
this.size++
}
func (this *MyLinkedListD) AddAtHead(val int) {
// 头部插入
node := &Node{Val: val}
if this.head != nil {
node.Next = this.head // 不断头部
this.head.Prev = node
this.head = node // 更新头部
} else { // 链表为空时
this.head = node
this.tail = this.head
}
// 更新size
this.size++
}
func (this *MyLinkedListD) AddAtTail(val int) {
// 尾部插入
node := &Node{Val: val}
if this.tail != nil {
node.Prev = this.tail
this.tail.Next = node
this.tail = node
} else {
this.tail = node
this.head = this.tail
}
// 更新size
this.size++
}
func (this *MyLinkedListD) DeleteAtIndex(index int) {
// 根据索引删除节点
if this.size == 0 || index < 0 || index >= this.size {
return
}
if index == 0 {
// 更新头部节点,相当于删除头结点
this.head = this.head.Next
} else if index == this.size - 1 {
// 更新尾部节点,相当于删除尾部节点
this.tail = this.tail.Prev
} else {
// 一般情况, 找到删除节点
cur := this.head
count := 0
for cur != nil && count < index {
count++
cur = cur.Next
}
cur.Next.Prev = cur.Prev
cur.Prev.Next = cur.Next
}
this.size--
}

posted on   进击的davis  阅读(64)  评论(0编辑  收藏  举报

编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示