1、list包详解,list实现了个双端队列
//这是一个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
len int // 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{}
使用用例
func Example() {
// Create a new list and put some numbers in it.
l := list.New()
e4 := l.PushBack(4) //插入到末尾
e1 := l.PushFront(1)//插入到头元素
l.InsertBefore(3, e4) //插入到e4元素之前
l.InsertAfter(2, e1)//插入e1元素之后
// Iterate through list and print its contents.
for e := l.Front(); e != nil; e = e.Next() {
fmt.Println(e.Value)
}
// Output:
// 1
// 2
// 3
// 4
}
2、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
Value interface{} // 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{}))
3、heap堆结构
//heap结构只写了一个接口
type Interface interface {
sort.Interface //接口的组合(接口继承),继承sort(排序接口),子类就可调用排序的方法
Push(x interface{}) // add x as element Len()
Pop() interface{} // remove and return element Len() - 1.
}
//要实现这个接口,必须实现所有的方法,包括继承了的接口
实现这五个方法,这五个方法可能实现个不一样,真真的需求完全交给用户
func down(i,n int) {
//构建最小堆,父小于两子节点值
for {
j1 := 2*i + 1
if j1 >= n || j1 < 0 { // j1 < 0 after int overflow
break
}
//找出两个节点中最小的(less: a<b)
j := j1 // left child
if j2 := j1 + 1; j2 < n && !Less(j1, j2) {
j = j2 // = 2*i + 2 // right child
}
//然后与父节点i比较,如果父节点小于这个子节点最小值,则break,否则swap
if !Less(j, i) {
break
}
Swap(i, j)
i = j
}
}
//由子节点至父节点依次重建堆
func up(j int) {
for {
i := (j - 1) / 2 // parent
if i == j || !Less(j, i) {
//less(子,父) !Less(9,5) == true
//父节点小于子节点,符合最小堆条件,break
break
}
//子节点比父节点小,互换
Swap(i, j)
j = i
}
}
func Push(x interface{}){
heap = append(heap, x.(int))
up(len(heap)-1)
return
}
func Pop() interface{} {
n := len(heap) - 1
Swap(0, n)
down(0, n)
old :=heap
n = len(old)
x := old[n-1]
heap = old[0 : n-1]
return x
}
func Remove(i int) interface{} {
n := len(heap) - 1
if n != i {
Swap(i, n)
down(i, n)
up(i)
}
return Pop()
}
func Less(a,b int)bool{
return heap[a] < heap[b]
func Swap(a,b int){
heap[a],heap[b] = heap[b],heap[a]
}
//源码中实现了一个堆排序需要的堆方法,就是上面的几个方法,下面这个就是一个堆排序的使用
func HeapSort(){
//升序 Less(heap[a] > heap[b]) //最大堆
//降序 Less(heap[a] < heap[b]) //最小堆
for i := len(heap)-1 ;i > 0;i--{
//移除顶部元素到数组末尾,然后剩下的重建堆,依次循环
Swap(0, i)
down(0, i)
}
}