基础数据结构----不带头结点的循环双链表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语言的实现的主要内容,如果未能解决你的问题,请参考以下文章

基础数据结构----不带头结点的循环双链表go语言的实现

基础数据结构---双链表go语言的代码实现

基础数据结构---双链表go语言的代码实现

C语言实现非循环双链表节点的删除(不带头结点)

C语言实现非循环双链表节点的删除(带头结点尾结点)

C实现头插法和尾插法来构建非循环双链表(不带头结点)