golang container包List和Ring
container/list
這個包包含了兩個公開的程式實體:List和Element。前者實現了一個雙向連結串列(以下簡稱連結串列),而後者則代表了連結串列中元素的結構。
//這是一個list中儲存的元素 type Element struct { // Next and previous pointers in the doubly-linked list of elements. // To simplify the implementation, internally a list l is implemented // as a ring, such that &l.root is both the next element of the last // list element (l.Back()) and the previous element of the first list // element (l.Front()). //包含一個指向下一個和上一個元素的指標,上面解釋說這是為了使用雙端佇列 next, prev *Element // The list to which this element belongs. //判斷這個元素是否屬於當前的list list *List // The value stored with this element. //儲存的值,使用interface來代替泛型 Value interface{} } //返回list的下一個元素 func (e *Element) Next() *Element{} //返回list的上一個元素 func (e *Element) Prev() *Element{}
//list結構 type List struct { //根元素,就是頭節點,頭節點的next,prev指向當前的元素 root Element // sentinel list element, only &root, root.prev, and root.next are used lenint// current list length excluding (this) sentinel element } list中的方法 // insert inserts e after at, increments l.len, and returns e. //插入e元素再at元素之後,就是指定插入 func (l *List) insert(e, at *Element) *Element{} // insertValue is a convenience wrapper for insert(&Element{Value: v}, at). //插入一個值到at元素中 func (l *List) insertValue(v interface{}, at *Element) *Element{} // remove removes e from its list, decrements l.len, and returns e. //刪除list中的e元素 func (l *List) remove(e *Element) *Element{} // PushFront inserts a new element e with value v at the front of list l and returns e. //插入一個元素在root的頭 func (l *List) PushFront(v interface{}) *Element{} //// PushBack inserts a new element e with value v at the back of list l and returns e. //插入一個元素在list的末尾 func (l *List) PushBack(v interface{}) *Element{} // 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. //插入一個新元素的值為v在mark之前並返回這個元素,若這個元素不是當前的list func (l *List) InsertBefore(v interface{}, mark *Element) *Element{} // 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. //插入一個元素,值為v,在mark的後面,並返回這個元素,如果mark不是當前list的元素,則list時不能修改的 func (l *List) InsertAfter(v interface{}, mark *Element) *Element{}
注意:語句var l list.List會是一個長度為0的連結串列。這個連結串列持有的根元素root也是一個空殼,其中只會包含預設的內容。但這樣的連結串列我們可以直接拿來使用,這被稱為開箱即用 。
其實單憑一個l是無法正常執行的,但關鍵不在這裡,而在於它的延遲初始化 機制。所謂的延遲初始化,你可以理解為把初始化操作延後,僅在需要的時候才執行。延遲初始化的優點在於延後 ,它可以分散初始化操作帶來的計算量和儲存空間消耗。
container/ring
ring包實現的是一個迴圈連結串列,也就是我們俗稱的環。
// A Ring is an element of a circular list, or ring. // Rings do not have a beginning or end; a pointer to any ring element // serves as reference to the entire ring. Empty rings are represented // as nil Ring pointers. The zero value for a Ring is a one-element // ring with a nil Value. // //環形連結串列的資料結構時一個環形list的元素或者圓環, //一個圓環連結串列是一個圓形list或者圓的元素,沒有開始和結束, type Ring struct { next, prev *Ring Valueinterface{} // for use by client; untouched by this library } // Next returns the next ring element. r must not be empty. //返回圓環的下一個元素,圓環必須不為空 func (r *Ring) Next() *Ring{} // Prev returns the previous ring element. r must not be empty. //返回這個圓環的上一個元素 func (r *Ring) Prev() *Ring{} //當n<0時,反向移動元素,n>0時,正向移動元素 func (r *Ring) Move(n int) *Ring{} //New creates a ring of n elements. //新建立n個集合的圓環 func New(n int) *Ring{} //統計 圓環長度 func (r *Ring) Len() int{} //Link連線r和s,並返回r原本的後繼元素r.Next()。r不能為空。如果r和s指向同一個環形連結串列,則會刪除掉r和s之間的元素,刪掉的元素構成一個子連結串列,返回指向該子連結串列的指標(r的原後繼元素);如果沒有刪除元素,則仍然返回r的原後繼元素,而不是nil。如果r和s指向不同的連結串列,將建立一個單獨的連結串列,將s指向的連結串列插入r後面,返回s原最後一個元素後面的元素(即r的原後繼元素)。 func (r *Ring) Link(s *Ring) *Ring{} //刪除連結串列中n % r.Len()個元素,從r.Next()開始刪除。如果n % r.Len() == 0,不修改r。返回刪除的元素構成的連結串列,r不能為空。 func (r *Ring) Unlink(n int) *Ring {} //對連結串列中任意元素執行f操作,如果f改變了r,則該操作造成的後果是不可預期的。 func (r *Ring) Do(f func(interface{}))
使用場景:
1.list的典型應用場景是構造FIFO佇列;
2.ring的典型應用場景是構造定長環回佇列,比如網頁上的輪播;