GOLANG-链表

GO语言的链表实现在其标准库的container/list代码包中。这个包包含了两个公开的程序实体List和Element。前者实现了一个双向链表,后者则代表了链表中元素的结构。

package list

// Element is an element of a linked list.

type Element struct {

    next, prev *Element

    // The list to which this element belongs.

    list *List

    // The value stored with this element.

    Value interface{}

}

// Next returns the next list element or nil.

func (e *Element) Next() *Element {

    if p := e.next; e.list != nil && p != &e.list.root {

        return p

    }

    return nil

}

 

// Prev returns the previous list element or nil.

func (e *Element) Prev() *Element {

    if p := e.prev; e.list != nil && p != &e.list.root {

        return p

    }

    return nil

}

 

// List represents a doubly linked list.

// The zero value for List is an empty list ready to use.

type List struct {

    root Element // sentinel list element, only &root, root.prev, and root.next are used

    len int // current list length excluding (this) sentinel element

}

 

// Init initializes or clears list l.

func (l *List) Init() *List {

    l.root.next = &l.root

    l.root.prev = &l.root

    l.len = 0

    return l

}

 

// New returns an initialized list.

func New() *List { return new(List).Init() }

 

// Len returns the number of elements of list l.

// The complexity is O(1).

func (l *List) Len() int { return l.len }

 

// Front returns the first element of list l or nil if the list is empty.

func (l *List) Front() *Element {

    if l.len == 0 {

        return nil

    }

    return l.root.next

}

 

// Back returns the last element of list l or nil if the list is empty.

func (l *List) Back() *Element {

    if l.len == 0 {

        return nil

    }

    return l.root.prev

}

 

// lazyInit lazily initializes a zero List value.

func (l *List) lazyInit() {

    if l.root.next == nil {

        l.Init()

    }

}

 

// insert inserts e after at, increments l.len, and returns e.

func (l *List) insert(e, at *Element) *Element {

    n := at.next

    at.next = e

    e.prev = at

    e.next = n

    n.prev = e

    e.list = l

    l.len++

    return e

}

 

// insertValue is a convenience wrapper for insert(&Element{Value: v}, at).

func (l *List) insertValue(v interface{}, at *Element) *Element {

    return l.insert(&Element{Value: v}, at)

}

 

// remove removes e from its list, decrements l.len, and returns e.

func (l *List) remove(e *Element) *Element {

    e.prev.next = e.next

    e.next.prev = e.prev

    e.next = nil // avoid memory leaks

    e.prev = nil // avoid memory leaks

    e.list = nil

    l.len--

    return e

}

 

// Remove removes e from l if e is an element of list l.

// It returns the element value e.Value.

// The element must not be nil.

func (l *List) Remove(e *Element) interface{} {

    if e.list == l {

        // if e.list == l, l must have been initialized when e was inserted

        // in l or l == nil (e is a zero Element) and l.remove will crash

        l.remove(e)

    }

    return e.Value

}

 

// PushFront inserts a new element e with value v at the front of list l and returns e.

func (l *List) PushFront(v interface{}) *Element {

    l.lazyInit()

    return l.insertValue(v, &l.root)

}

 

// PushBack inserts a new element e with value v at the back of list l and returns e.

func (l *List) PushBack(v interface{}) *Element {

    l.lazyInit()

    return l.insertValue(v, l.root.prev)

}

 

// InsertBefore inserts a new element e with value v immediately before mark and returns e.

// If mark is not an element of l, the list is not modified.

// The mark must not be nil.

func (l *List) InsertBefore(v interface{}, mark *Element) *Element {

    if mark.list != l {

        return nil

    }

    // see comment in List.Remove about initialization of l

    return l.insertValue(v, mark.prev)

}

 

// InsertAfter inserts a new element e with value v immediately after mark and returns e.

// If mark is not an element of l, the list is not modified.

// The mark must not be nil.

func (l *List) InsertAfter(v interface{}, mark *Element) *Element {

    if mark.list != l {

        return nil

    }

    // see comment in List.Remove about initialization of l

    return l.insertValue(v, mark)

}

 

// MoveToFront moves element e to the front of list l.

// If e is not an element of l, the list is not modified.

// The element must not be nil.

func (l *List) MoveToFront(e *Element) {

    if e.list != l || l.root.next == e {

        return

    }

    // see comment in List.Remove about initialization of l

    l.insert(l.remove(e), &l.root)

}

 

// MoveToBack moves element e to the back of list l.

// If e is not an element of l, the list is not modified.

// The element must not be nil.

func (l *List) MoveToBack(e *Element) {

    if e.list != l || l.root.prev == e {

        return

    }

    // see comment in List.Remove about initialization of l

    l.insert(l.remove(e), l.root.prev)

}

 

// MoveBefore moves element e to its new position before mark.

// If e or mark is not an element of l, or e == mark, the list is not modified.

// The element and mark must not be nil.

func (l *List) MoveBefore(e, mark *Element) {

    if e.list != l || e == mark || mark.list != l {

        return

    }

    l.insert(l.remove(e), mark.prev)

}

 

// MoveAfter moves element e to its new position after mark.

// If e or mark is not an element of l, or e == mark, the list is not modified.

// The element and mark must not be nil.

func (l *List) MoveAfter(e, mark *Element) {

    if e.list != l || e == mark || mark.list != l {

        return

    }

    l.insert(l.remove(e), mark)

}

 

// PushBackList inserts a copy of an other list at the back of list l.

// The lists l and other may be the same. They must not be nil.

func (l *List) PushBackList(other *List) {

    l.lazyInit()

    for i, e := other.Len(), other.Front(); i > 0; i, e = i-1, e.Next() {

        l.insertValue(e.Value, l.root.prev)

    }

}

 

// PushFrontList inserts a copy of an other list at the front of list l.

// The lists l and other may be the same. They must not be nil.

func (l *List) PushFrontList(other *List) {

    l.lazyInit()

    for i, e := other.Len(), other.Back(); i > 0; i, e = i-1, e.Prev() {

        l.insertValue(e.Value, &l.root)

    }

}

 

转载于:https://my.oschina.net/u/3980073/blog/2223049

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值