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)
}