数据结构【Golang实现】(四)——双向循环链表
2023-06-13 09:18:38 时间
0. 定义节点
type DLNode struct {
Data any
Prev, 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.headNode
count := 1
for 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 = node
return
}
currentNode := l.headNode
for currentNode.Next != l.headNode { // 遍历到尾结点
currentNode = currentNode.Next
}
currentNode.Next = node
l.headNode.Prev = node
node.Prev = currentNode
node.Next = l.headNode
l.headNode = node
}
4. AddFromTail()
// AddFromTail 从双向循环链表尾部增加节点
func (l *DoublyLoopLinkedList) AddFromTail(data any) {
node := &DLNode{Data: data}
if l.IsEmpty() {
l.headNode = node
return
}
currentNode := l.headNode
for currentNode != l.headNode { // 遍历到尾结点
currentNode = currentNode.Next
}
currentNode.Next = node
l.headNode.Prev = node
node.Prev = currentNode
node.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 := 0
currentNode := l.headNode
for count != position {
count++
currentNode = currentNode.Next
}
node.Next = currentNode
node.Prev = currentNode.Prev
currentNode.Prev.Next = node
currentNode.Prev = node
}
}
6. DeleteHead()
// DeleteHead 删除链表头结点
func (l *DoublyLoopLinkedList) DeleteHead() {
if l.IsEmpty() {
fmt.Println("Doubly Linked List is Empty")
return
}
currentNode := l.headNode
if currentNode.Next == l.headNode { // 只有一个节点的情况
l.headNode = nil
return
} else {
for currentNode.Next != l.headNode { // 遍历到倒数第一个节点
currentNode = currentNode.Next
}
currentNode.Next = l.headNode.Next
l.headNode.Next.Prev = currentNode
l.headNode = l.headNode.Next
}
}
7. DeleteTail()
// DeleteTail 删除链表尾结点
func (l *DoublyLoopLinkedList) DeleteTail() {
if l.IsEmpty() {
fmt.Println("Doubly Linked List is Empty")
return
}
currentNode := l.headNode
if currentNode.Next == l.headNode { // 只有一个节点的情况
l.headNode = nil
return
} else {
for currentNode.Next != l.headNode {
currentNode = currentNode.Next
}
currentNode.Prev.Next = l.headNode
l.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 := 0
currentNode := l.headNode
for count != position {
count++
currentNode = currentNode.Next
}
currentNode.Prev.Next = currentNode.Next
currentNode.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.headNode
if currentNode.Data == data { // 比较头结点
l.DeleteHead()
return
}
for currentNode.Next != l.headNode { // 这里是跳过了头结点的
if currentNode.Next.Data == data {
currentNode.Next.Prev.Next = currentNode.Next.Next
currentNode.Next.Next.Prev = currentNode.Next.Prev
return
} else {
currentNode = currentNode.Next
}
}
}
10. Contain()
// Contain 查询双向循环链表是否包含某个节点
func (l *DoublyLoopLinkedList) Contain(data any) bool {
if l.IsEmpty() {
return false
}
currentNode := l.headNode
for 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.headNode
for currentNode.Next != l.headNode {
fmt.Printf("%v -> ", currentNode.Data)
currentNode = currentNode.Next
}
fmt.Printf("%v\n", currentNode.Data)
}
相关文章
- 循环单链表解决约瑟夫环_用链表解决约瑟夫环问题
- Shell循环遍历日期「建议收藏」
- 循环链表的实现_建立双向循环链表
- 双向带头循环链表的(增删查改)的实现
- 进阶分支语句和使用while循环及break语句
- 约瑟夫环问题(单向循环链表实现)
- if循环
- 单向循环链表-《数据结构》自学方法指导
- 单循环链表-带头双向循环链表的实现
- 单循环链表-这么好的单链表结构怎么能不会呢?带哨兵位头节点双向循环链表
- 【线性表】—不带头单向非循环链表的增删查改
- 彻底搞懂nodejs事件循环_2023-03-15
- Python for循环语句
- Linux 下稳定的Ping循环测试(linux循环ping)
- Ruby中循环引用导致lighttpd中的ruby fcgi脚本执行失败(Mac OS)
- 使用 Oracle 构建循环语句的实战技巧(oracle使用循环语句)
- Oracle如何中断循环实现更高效(oracle 中断循环)
- 如何在Oracle中实现循环(Oracle中怎么循环)
- C#数据结构之循环链表的实例代码
- java双向循环链表的实现代码
- JavaMap的几种循环方式总结