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

Posted 有关于S27的故事

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实现头插法和尾插法来构建非循环双链表(不带头结点)