链表

    链表是一种物理存储单元上非连续、非顺序的存储结构数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

 

 使用Go自带的container/list实现双向链表

import (
    "container/list"
    "fmt"
)

//正向遍历链表
func TraversList(lst *list.List){
    //拿到链表的首元素
    head:=lst.Front()
    for head.Next()!=nil{
        fmt.Printf("%v",head.Value)
        head=head.Next()
    }
    fmt.Printf("%v\n",head.Value)        //打印出末尾元素
}

//反向遍历链表
func ReverseList(lst *list.List){
    tail := lst.Back()
    for tail.Prev()!= nil {
        fmt.Printf("%v",tail.Value)
        tail=tail.Prev()
    }
    fmt.Printf("%v\n",tail.Value)
}

//使用list创建链表
func testList(){
    lst:=list.New()
    //链表尾部添加元素
    lst.PushBack(1)
    //链表首部添加元素
    lst.PushFront(4)
    lst.PushFront(2)
    lst.PushFront(1)    //1 2 4 1
    lst.PushFront(5)
    lst.PushFront(4)
    lst.PushFront(2) 
    TraversList(lst)
    ReverseList(lst)
    //删除尾部元素
    lst.Remove(lst.Back())    //O(1)
    //删除首部元素
    lst.Remove(lst.Front())    //O(1)

    fmt.Printf("len:%d\n",lst.Len())

    TraversList(lst)    //45124

    //删除任意位置元素
    target :=lst.Back().Prev().Prev()
    lst.Remove(target)
    target = lst.Front().Next()
    lst.Remove(target)

    TraversList(lst)    //424
}

 使用Go语言自己实现双向链表

package main

import "fmt"

//创建链表的节点
type Node struct {
    Value int
    Prev *Node
    Next *Node
}
//双向链表的方法
type DoubleList struct {
    Head *Node
    Tail *Node
    Lenght int
}

//末尾添加元素
func (list *DoubleList) Append(x int) {
    node:= &Node{
        Value: x,
        Prev: nil,
        Next: nil,
    }
    if list.Tail != nil {
        list.Tail.Next=node
        node.Prev = list.Tail
        list.Tail = node
    }else{    //代表链表为空
        list.Tail=node
        list.Head=node
    }
    list.Lenght +=1
}

//首部添加元素
func (list *DoubleList) Headjoin(va int) {
    node:=&Node{
        Value: va,
        Prev: nil,
        Next: nil,
    }
    if list.Head != nil {
        list.Head.Prev = node
        node.Next = list.Head
        list.Head = node
    } else {    //代表链表为空
        list.Head = node
        list.Tail = node
    }
}

// 根据下标获取元素
func (list *DoubleList) Get(index int) *Node{
    //下标数不能大于或者等于链表的总长度
    if list.Lenght <= index {
        return nil
    }
    curr:=list.Head
    //通过遍历一直获取下一个node直到获取到下标位置
    for i:=0;i<index;i++{
        curr=curr.Next
    }
    return curr
}

//插入到指定下标后
func (list *DoubleList) InsterAfter(prevNode *Node,va int){
    node:= &Node{
        Value: va,
        Prev: nil,
        Next: nil,
    }
    if prevNode.Next==nil {
        prevNode.Next=node
        node.Prev=prevNode
    }else {
        //获取指定下标的后一个node
        nextNode:=prevNode.Next
        
          //将要插入的元素和指定下标的下一个元素,做好对应关系
        nextNode.Prev = node
        node.Next=nextNode

        //将要插入的元素和指定下标的元素,做好对应关系
        prevNode.Next = node
        node.Prev = prevNode
    }
    list.Lenght+=1
}

//遍历链表
func (list *DoubleList) Traverse() {
    curr:=list.Head
    for curr != nil {
        fmt.Printf("%d",curr.Value)
        curr=curr.Next
    }
    fmt.Println()
}