基础数据结构----不带头结点的循环双链表go语言的实现
Posted 老虎中的小白Gentle
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基础数据结构----不带头结点的循环双链表go语言的实现相关的知识,希望对你有一定的参考价值。
/*
不带头结点的循环双链表
*/
package main
import (
"errors"
"fmt"
)
//链表的结构体
type Node struct {
key int
value string
pre *Node
next *Node
}
//创建一个链表
func newList(key int, value string) (list *Node) {
list = & Node{
key:key,
value: value,
}
list.pre = list
list.next = list
return list
}
//尾插法
func addNode(list,newNode *Node) {
if list == nil {
fmt.Println("链表为空")
return
}
//先新结点分别指向他们,尾插法
newNode.pre = list.pre
newNode.next = list
//再让他们分别指向新结点
newNode.pre.next = newNode //等价于 list.next = newNode
newNode.next.pre = newNode //等价于 list.next.pre = newNode
}
//头插法
func addNodeLeft(list, newNode *Node) {
if list == nil {
fmt.Println("链表为空")
return
}
newNode.next = list
newNode.pre = list.pre
newNode.pre.next = newNode
newNode.next.pre = newNode
}
//展示链表 ,从头到尾展示
func showListHead(list *Node) {
if list == nil {
fmt.Println("链表为空")
return
}
tmp := list
for {
fmt.Printf(">>key:%d,value:%s",tmp.key,tmp.value)
tmp = tmp.next
if tmp == list {
//到这里的时候,链表已经遍历完成了
break
}
}
fmt.Println()
}
//展示链表,从尾到头
func showListTail(list *Node) {
if list == nil {
fmt.Println("链表为空")
return
}
tmp := list
for {
fmt.Printf(">>key:%d,value:%s",tmp.key,tmp.value)
tmp = tmp.pre
if tmp == list {
//到这里的时候,链表已经遍历完成了
break
}
}
fmt.Println()
}
//按值插入
func insertByKey(list, newNode *Node) (err error){
if list == nil {
err = errors.New("链表为空")
return
}
//定义一个跑龙套
tmp := list
for {
if tmp.key >newNode.key {
//找了第一个比新结点大的,插入到它前面
//先将新结点指好
newNode.next = tmp
newNode.pre = tmp.pre
//再讲其他结点指向新结点
newNode.pre.next = newNode
newNode.next.pre = newNode
break
}
if tmp.next == list {
//找不到一个比新结点大的,就插入到链表的“最后一个”
//1.
newNode.pre = tmp.next.pre //等价于 newNode.pre = list.pre
newNode.next = tmp.next //等价于 newNode.next = list
//2.
newNode.pre.next = newNode
newNode.next.pre = newNode
break
}
tmp = tmp.next
}
return
}
//按值删除
func delByKey(list *Node, key int)(err error) {
if list == nil {
err = errors.New("链表为空")
return
}
tmp := list
for {
if tmp.key == key {
//找到了要删除的结点
//跳过要删除的结点
tmp.pre.next = tmp.next
tmp.next.pre = tmp.pre
break
}
tmp = tmp.next
}
//找不到该值
err = errors.New("在这个链表里面,找不到该值")
return
}
//测试上面的方法
func main() {
list := newList(000,"000")
node1 := &Node {
key: 111,
value: "111",
}
node2 := &Node{
key: 222,
value: "222",
}
node3 := &Node{
key: 333,
value: "333",
}
showListHead(list)
addNode(list,node1)
showListHead(list)
addNode(list,node2)
showListHead(list)
addNode(list,node3)
fmt.Println("+++++++++++++++++++++++++++++")
showListHead(list)
showListTail(list)
node4 := &Node {
key: 444,
value: "444",
}
node5 := &Node {
key: 555,
value: "555",
}
err := insertByKey(list,node5)
if err !=nil {
fmt.Println("call insertByKey1 err=",err)
return
}
fmt.Println("-------------5555555---------------")
showListTail(list)
showListHead(list)
err = insertByKey(list,node4)
if err !=nil {
fmt.Println("call insertByKey1 err=",err)
return
}
fmt.Println("-------------44444---------------")
showListTail(list)
showListHead(list)
fmt.Println("===============================")
list2 := newList(0,"0")
addNodeLeft(list2,node1)
addNodeLeft(list2,node2)
addNodeLeft(list2,node3)
addNodeLeft(list2,node4)
addNodeLeft(list2,node5)
showListTail(list2)
showListHead(list2)
}
以上是关于基础数据结构----不带头结点的循环双链表go语言的实现的主要内容,如果未能解决你的问题,请参考以下文章