当前位置: 首页 > news >正文

数据结构【Golang实现】(四)——双向循环链表

目录

  • 0. 定义节点
  • 1. IsEmpty()
  • 2. Length()
  • 3. AddFromHead()
  • 4. AddFromTail()
  • 5. Insert()
  • 6. DeleteHead()
  • 7. DeleteTail()
  • 8. Remove()
  • 9. RemoveByValue()
  • 10. Contain()
  • 11. Traverse()

0. 定义节点

type DLNode struct {Data       anyPrev, Next *DLNode
}// DoublyLoopLinkedList 双向循环链表
type DoublyLoopLinkedList struct {headNode *DLNode
}

1. IsEmpty()

// IsEmpty 判断链表是否为空
func (l *DoublyLoopLinkedList) IsEmpty() bool {if l.headNode == nil {return true}return false
}

2. Length()

// Length 获取链表长度
func (l *DoublyLoopLinkedList) Length() int {if l.IsEmpty() {return 0}currentNode := l.headNodecount := 1for currentNode.Next != l.headNode {count++currentNode = currentNode.Next}return count
}

3. AddFromHead()

// AddFromHead 从双向循环链表头部增加节点
func (l *DoublyLoopLinkedList) AddFromHead(data any) {node := &DLNode{Data: data}if l.IsEmpty() {l.headNode = nodereturn}currentNode := l.headNodefor currentNode.Next != l.headNode { // 遍历到尾结点currentNode = currentNode.Next}currentNode.Next = nodel.headNode.Prev = nodenode.Prev = currentNodenode.Next = l.headNodel.headNode = node
}

4. AddFromTail()

// AddFromTail  从双向循环链表尾部增加节点
func (l *DoublyLoopLinkedList) AddFromTail(data any) {node := &DLNode{Data: data}if l.IsEmpty() {l.headNode = nodereturn}currentNode := l.headNodefor currentNode != l.headNode { // 遍历到尾结点currentNode = currentNode.Next}currentNode.Next = nodel.headNode.Prev = nodenode.Prev = currentNodenode.Next = l.headNode
}

5. Insert()

// Insert  从双向循环链表指定位置增加节点 下标从0开始
func (l *DoublyLoopLinkedList) Insert(position int, data any) {if position <= 0 {l.AddFromHead(data)return} else if position >= l.Length()-1 {l.AddFromTail(data)return} else {node := &DLNode{Data: data}count := 0currentNode := l.headNodefor count != position {count++currentNode = currentNode.Next}node.Next = currentNodenode.Prev = currentNode.PrevcurrentNode.Prev.Next = nodecurrentNode.Prev = node}
}

6. DeleteHead()

// DeleteHead 删除链表头结点
func (l *DoublyLoopLinkedList) DeleteHead() {if l.IsEmpty() {fmt.Println("Doubly Linked List is Empty")return}currentNode := l.headNodeif currentNode.Next == l.headNode { // 只有一个节点的情况l.headNode = nilreturn} else {for currentNode.Next != l.headNode { // 遍历到倒数第一个节点currentNode = currentNode.Next}currentNode.Next = l.headNode.Nextl.headNode.Next.Prev = currentNodel.headNode = l.headNode.Next}
}

7. DeleteTail()

// DeleteTail 删除链表尾结点
func (l *DoublyLoopLinkedList) DeleteTail() {if l.IsEmpty() {fmt.Println("Doubly Linked List is Empty")return}currentNode := l.headNodeif currentNode.Next == l.headNode { // 只有一个节点的情况l.headNode = nilreturn} else {for currentNode.Next != l.headNode {currentNode = currentNode.Next}currentNode.Prev.Next = l.headNodel.headNode.Prev = currentNode.Prev}
}

8. Remove()

// Remove 删除链表指定位置结点
func (l *DoublyLoopLinkedList) Remove(position int) {if position <= 0 {l.DeleteHead()return} else if position >= l.Length()-1 {l.DeleteTail()return} else {count := 0currentNode := l.headNodefor count != position {count++currentNode = currentNode.Next}currentNode.Prev.Next = currentNode.NextcurrentNode.Next.Prev = currentNode.Prev}
}

9. RemoveByValue()

// RemoveByValue 删除链表指定值的节点
func (l *DoublyLoopLinkedList) RemoveByValue(data any) {if l.IsEmpty() {fmt.Println("Doubly Linked List is Empty")return}currentNode := l.headNodeif currentNode.Data == data { // 比较头结点l.DeleteHead()return}for currentNode.Next != l.headNode { // 这里是跳过了头结点的if currentNode.Next.Data == data {currentNode.Next.Prev.Next = currentNode.Next.NextcurrentNode.Next.Next.Prev = currentNode.Next.Prevreturn} else {currentNode = currentNode.Next}}
}

10. Contain()

// Contain 查询双向循环链表是否包含某个节点
func (l *DoublyLoopLinkedList) Contain(data any) bool {if l.IsEmpty() {return false}currentNode := l.headNodefor currentNode.Next != l.headNode {if currentNode.Data == data {return true} else {currentNode = currentNode.Next}}if currentNode.Data == data {return true}return false
}

11. Traverse()

// Traverse 遍历双向循环链表
func (l *DoublyLoopLinkedList) Traverse() {if l.IsEmpty() {fmt.Println("Doubly Linked List is Empty")return}currentNode := l.headNodefor currentNode.Next != l.headNode {fmt.Printf("%v -> ", currentNode.Data)currentNode = currentNode.Next}fmt.Printf("%v\n", currentNode.Data)
}
http://www.lryc.cn/news/39305.html

相关文章:

  • 【Redis】高可用架构之哨兵模式 - Sentinel
  • 图片的美白与美化
  • 面试官:关于CPU你了解多少?
  • UI自动化测试-Selenium的使用
  • 嵌入式学习笔记——STM32的USART相关寄存器介绍及其配置
  • Android setContentView流程分析(一)
  • doris数据库操作数字遇到的问题
  • 3.13文件的IO操作
  • ffmpeg使用
  • spark中的并行度(分区数)/分区器如何确定
  • 00后女生“云摆摊”两周赚1.5万,实体店转战线上真的能赚钱吗?
  • 华为OD机试题 - 最优资源分配(JavaScript)| 机考必刷
  • 利用python判断字符串是否为回文
  • GDB 调用之ptype、set variable
  • 并发编程---阻塞队列(五)
  • 本科课程【计算机组成原理】实验1 - 输出ABCD程序的生成
  • Java并发编程(2) —— 线程创建的方式与原理
  • 你写的js性能有多差你知道吗 | js性能优化
  • 线程的状态、状态之间的相互转换
  • Java8使用Lambda表达式(流式)快速实现List转map 、分组、过滤等操作
  • C++之深浅拷贝
  • CoreLocation的一切
  • HashMap原理
  • STM32入门笔记(02):独立看门狗(IWDG)和窗户看门狗(WWDG)(SPL库函数版)
  • javaSE系列之方法与数组的使用
  • 常用命令总结
  • 【Linux:程序地址空间--原来操作系统也喜欢画大饼】
  • Python实现简单信号滤波实战
  • Java(110):非对称加密RSA的使用(KeyPair生成密钥)
  • (Mybatis 学习【1】)整合 Mybatis 开发流程