Golang内建库学习笔记(1)-sort和container

sort库

利用sort.Sort进行排序须实现如下接口

type Interface interface {
        // 获取数据集合元素个数
        Len() int
        // 如果i索引的数据小于j所以的数据,返回true,不会调用
        // 下面的Swap(),即数据升序排序。
        Less(i, j int) bool
        // 交换i和j索引的两个元素的位置
        Swap(i, j int)
}

然后即可使用Sort(),Search(),IsSorted(), Reverse()方法

其中Search()方法使用方法如下:

    x := 11
    s := []int{3, 6, 8, 11, 45} //注意已经升序排序
    pos := sort.Search(len(s), func(i int) bool { return s[i] >= x })

注意:func(i int) bool {return s[i]>=x},这里Search返回的是符合条件的最小的index。相当于这里的func返回的是slice一侧数值均符合的条件的判断情况。

sort库内建了对[]int, []float64, []string三种类型的排序。

func Float64s(a []float64)  
func Float64sAreSorted(a []float64) bool
func SearchFloat64s(a []float64, x float64) int

或类似的其它方法。

container库

container库主要提供了堆,双向链表和环三种数据结构

堆的接口定义如下:

type Interface interface {
    sort.Interface
    Push(x interface{}) // add x as element Len()
    Pop() interface{}   // remove and return element Len() - 1.
}

可以看到堆除了需要实现sort的Len,Less和Swap三个方法以外,还要实现Push和Pop两个方法。

测试代码如下:

import (
    "container/heap"
    "fmt"
)

type IntHeap []int

func (h IntHeap) Len() int {
    return len(h)
}

func (h IntHeap) Less(i,j int) bool {
    return h[i]<h[j]
}

func (h IntHeap) Swap(i,j int) {
    h[i], h[j] = h[j], h[i]
}

func (h *IntHeap) Push(i interface{}) {
    *h = append(*h, i.(int))
}

func (h *IntHeap) Pop() interface{} {
    temp := *h
    l := len(temp)
    n := temp[l-1]
    *h = temp[0:l-1]
    return n
}

func ContainerTest() {
    h := &IntHeap{1,3,5,7,9,2,4,6,8,10}
    heap.Init(h)
    fmt.Println(h)
    heap.Push(h,0)
    fmt.Println(h)
}

注意,声明变量的时候,要声明为堆的地址。

双向链表

双向链表的结构如下:

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

    // The value stored with this element.
    Value interface{}
}

可以看到双向链表中记录了每个节点的前后节点指针,所在的双向链表指针,以及该节点的值。

双向链表提供了以下方法供调用:

type Element
    func (e *Element) Next() *Element
    func (e *Element) Prev() *Element
type List
    func New() *List
    func (l *List) Back() *Element   // 最后一个元素
    func (l *List) Front() *Element  // 第一个元素
    func (l *List) Init() *List  // 链表初始化
    func (l *List) InsertAfter(v interface{}, mark *Element) *Element // 在某个元素后插入
    func (l *List) InsertBefore(v interface{}, mark *Element) *Element  // 在某个元素前插入
    func (l *List) Len() int // 在链表长度
    func (l *List) MoveAfter(e, mark *Element)  // 把e元素移动到mark之后
    func (l *List) MoveBefore(e, mark *Element)  // 把e元素移动到mark之前
    func (l *List) MoveToBack(e *Element) // 把e元素移动到队列最后
    func (l *List) MoveToFront(e *Element) // 把e元素移动到队列最头部
    func (l *List) PushBack(v interface{}) *Element  // 在队列最后插入元素
    func (l *List) PushBackList(other *List)  // 在队列最后插入接上新队列
    func (l *List) PushFront(v interface{}) *Element  // 在队列头部插入元素
    func (l *List) PushFrontList(other *List) // 在队列头部插入接上新队列
    func (l *List) Remove(e *Element) interface{} // 删除某个元素
原文地址:https://www.cnblogs.com/wangzhao765/p/9027632.html