双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
代码如下:
package doubleLinkedList
import (
"errors"
"fmt"
)
type ElemType interface{}
//结点
type Node struct {
Data ElemType
Pre *Node
Next *Node
}
//链表
type List struct {
First *Node
Last *Node
Size int
}
//工厂函数
func CreateList() *List {
s := new(Node)
s.Next, s.Pre = s, s
return &List{s, s, 0}
}
//尾插法
func (list *List) PushBack(x ElemType) {
s := new(Node)
s.Data = x
list.Last.Next = s
s.Pre = list.Last
list.Last = s
list.Last.Next = list.First
list.First.Pre = list.Last
list.Size++
}
//头插法
func (list *List) PushFront(x ElemType) {
s := new(Node)
s.Data = x
s.Next = list.First.Next
list.First.Next.Pre = s
list.First.Next = s
s.Pre = list.First
if list.Size == 0 {
list.Last = s
}
list.Size++
}
//尾删法
func (list *List) PopBack() bool {
if list.IsEmpty() {
return false
}
s := list.Last.Pre //找到最后一个节点的前驱
s.Next = list.First
list.Last = s
list.Size--
return true
}
//头删法
func (list *List) PopFront() bool {
if list.IsEmpty() {
return false
}
s := list.First.Next //找到第一个节点
list.First.Next = s.Next
s.Next.Pre = list.First
if list.Size == 1 {
list.Last = list.First
}
list.Size--
return true
}
//查找指定元素
func (list *List) Find(x ElemType) *Node {
s := list.First.Next
for s != list.First {
if x == s.Data {
return s
} else {
s = s.Next
}
}
return nil
}
//按值删除结点
func (list *List) DeleteVal(x ElemType) bool {
s := list.Find(x)
if s != nil {
s.Pre.Next = s.Next
s.Next.Pre = s.Pre
list.Size--
//如果删除的是最后一个结点
if s == list.Last {
list.Last = s.Pre
}
return true
}
return false
}
//把值为x的元素的值修改为y
func (list *List) Modify(x, y ElemType) bool {
s := list.Find(x)
if s != nil {
s.Data = y
return true
}
return false
}
//判断链表是否为空
func (list *List) IsEmpty() bool {
return list.Size == 0
}
//反转链表
//保留第一个结点,将剩余的结点游离出来,然后依次头插到保留的结点中
func (list *List) Reverse() {
if list.Size > 1 {
s := list.First.Next
p := s.Next
s.Next = list.First //第一个结点逆置后成为最后一个结点
list.Last = s
for p != list.First {
s = p
p = p.Next
s.Next = list.First.Next
list.First.Next.Pre = s
s.Pre = list.First
list.First.Next = s
}
}
}
//打印链表
func (list *List) Print() error {
if list.IsEmpty() {
return errors.New("this is an empty list")
}
s := list.First.Next
for s != list.First {
fmt.Printf("%v ", s.Data)
s = s.Next
}
fmt.Println()
return nil
}
简单使用了一下:
package main
import (
"learngo/lang/datastruct/doublelinkedlist"
)
func main() {
list := doubleLinkedList.CreateList()
s := []int{1, 2, 3, 4, 5, 6, 7}
for _, v := range s {
list.PushBack(v)
}
//list.Print()
list.Modify(5, 55)
list.Print()
list.DeleteVal(7)
list.Print()
list.PopBack()
list.Print()
list.PopFront()
list.Print()
list.Reverse()
list.Print()
}
输出结果:
1 2 3 4 55 6 7
1 2 3 4 55 6
1 2 3 4 55
2 3 4 55
55 4 3 2
参考文章:https://blog.csdn.net/ZongYinHu/article/details/45490133