Go数据结构与算法-双向链表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yang731227/article/details/85059908

title: Go数据结构与算法-双向链表
tags: go,算法

介绍

和单链表比较,双向链表的元素不但知道自己下一个节点,还知道自己的上一个节点。
向后面车厢的箭头,车尾只有指向前面车厢的箭头。

图里面可以看出,每个车厢除了一个指向后面车厢的箭头外,还有一个指向前面车厢的箭头(车头、车尾除外)。车头只有指

和单向链表相比的优势

  • 插入删除不需要移动元素外,可以原地插入删除
  • 可以双向遍历

演示


package main

import "fmt"

type  LinkList interface {
	Clear() //清空
	Len()//求长度
	Front()*Element //第一个
	Back()*Element //最后一个
	Remove(e *Element) * Element
	Setdata(old,new interface{})
	Insert(e,mark *Element)*Element
	InsertValue(v interface{},mark *Element)*Element
	PushFront(data  interface{})*Element
	PushBack(data  interface{})*Element
	InsertBefore(data  interface{},mark *Element)*Element
	InsertAfter(data  interface{},mark *Element)*Element
	MoveBrfore(e,mark *Element)
	MoveAfter(e,mark *Element)
	Show()
}

type Element struct{
	prev,next *Element //前一个指针,后一个指针
	value  interface{}  //数据
	list * List
}

type List struct{
	root Element  //根元素,长度
	len int
}


func  New() *List{
	list:=new(List)
	list.Clear() //清空
	return list
}
func (list *List) Clear(){
	if firstelem:=list.root.next;firstelem!=nil && firstelem.list==list{
		firstelem.prev=nil
	}
	if lastelem:=list.root.prev;lastelem!=nil && lastelem.list==list{
		lastelem.prev=nil
	}
	list.root.next=&list.root
	list.root.prev=&list.root
	list.len=0
}
func (list *List) Len()int {
	return list.len
}
func (list *List)Front() *Element{
	if  list.len==0{
		return nil
	}
	return list.root.next//第一个节点
}

func (list *List) Back()*Element{
	if  list.len==0{
		return nil
	}
	return list.root.prev//最后一个节点
}
func (list *List) Insert(e,mark *Element)*Element{
	nbak :=mark.next  //备份
	mark.next =e
	e.prev=mark
	e.next=nbak
	nbak.prev=e
	e.list=list //保存链表的都指针
	list.len++ //长度+1
	return e

}
func (list *List) InsertValue(v interface{},mark *Element)*Element{
	return list.Insert(&Element{value:v},mark) //插入
}

func (list *List) PushFront(data  interface{})*Element{
	return list.InsertValue(data,&list.root) //前面插入
}
func (list *List) PushBack(data  interface{})*Element{
	return list.InsertValue(data,list.root.prev) //后面插入
}
//删除
func (list *List)Remove(e* Element)* Element{
	e.prev.next=e.next
	e.next.prev=e.prev
	e.next=nil
	e.prev=nil
	e.list=nil
	list.len--
	return e
}
//删除指定数据
func (list *List)Removedata(data interface{}) interface{}{
	for phead:=list.root.next;phead!=&list.root;phead=phead.next{
		if phead.value==data{
			list.Remove(phead)  //查找并删除
			return phead.value

		}

	}
	return nil
}
func (list *List) Show(){
	fmt.Println("链表开始")
	for phead:=list.root.next;phead!=&list.root;phead=phead.next{
		fmt.Println(phead.value)
	}
	fmt.Println("链表结束")
}
func (list *List)InsertBefore(data  interface{},mark *Element)*Element{
	if mark.list!=list{  //没有前置
		return nil
	}
	return list.InsertValue(data,mark.prev)
}
func (list *List)InsertAfter(data  interface{},mark *Element)*Element{
	if mark.list!=list{  //没有前置
		return nil
	}
	return list.InsertValue(data,mark)
}
func (list *List)MoveBrfore(e,mark *Element){
	if e.list!=list || list.root.next==e{
		return
	}

	list.Insert(list.Remove(e),mark.prev)
}
func (list *List)ReMoveAfter(e,mark *Element){
	if e.list!=list || list.root.prev==e{
		return
	}
	list.Insert(list.Remove(e),&list.root)
}
func (list *List) Setdata(old,new interface{}){
	for phead:=list.root.next;phead!=&list.root;phead=phead.next{
		if phead.value==old{
			phead.value=new  //更新
		}
		//fmt.Println(phead.value)
	}
}

func main(){
	mylist:=New()
	mylist.PushFront(1)
	mylist.PushFront(2)
	mylist.PushFront(3)
	mylist.PushFront(4)
	fmt.Println(mylist.root.value)
	fmt.Println(mylist.root.next.value)
	fmt.Println(mylist.root.next.next.value)
	fmt.Println(mylist.root.next.next.next.value)
	fmt.Println(mylist.root.next.next.next.next.value)
	
}

猜你喜欢

转载自blog.csdn.net/yang731227/article/details/85059908