基础数据结构----不带头结点的循环双链表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)

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

困了就喝白茶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值