go语言实现--双向循环链表

双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
这里写图片描述

代码如下:

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

猜你喜欢

转载自blog.csdn.net/tuobicui6522/article/details/80468677
今日推荐