Golang --- sort 包

Sort presentation package

  Go language standard library sort package is implemented in several basic sorting algorithms: insertion sort, quick sort and heap sort, but when using the sort packages do not need to specifically consider what sort sort used because the method based on incoming the amount of data to be sorted automatically select the appropriate sort algorithm.

InsertionSort FUNC (Data Interface, A, B int ) // insertion sort
heapSort FUNC (Data Interface, A, B int ) // heapsort
QUICKSORT FUNC (Data Interface, A, B, maxDepth int ) // Quicksort

  sort.Interface interface defines the following three methods, this is achieved as long as the three methods, the data can be sorted set, sort the package will automatically select efficient sorting algorithm based on actual data.

// sort.go
type Interface interface {
    // Len is the number of elements in the collection.
    Len() int
    // Less reports whether the element with
    // index i should sort before the element with index j.
    Less(i, j int) bool
    // Swap swaps the elements with indexes i and j.
    Swap(i, j int)
}

Sort package comes with the realization sort

  Go in the sort package, give us achieve three types of ordering, are Int, string, float64 type, let's look at the specific type of implementation Int:

// sort.go
// IntSlice attaches the methods of Interface to []int, sorting in increasing order.
type IntSlice []int

Func (p IntSlice) Len () int            { return len (p)}
func (p IntSlice) Less(i, j int) bool { return p[i] < p[j] }
func (p IntSlice) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }

// Sort is a convenience method.
func (p IntSlice) Sort() { Sort(p) }

  Go see've given int array implements these three methods, two other types of basically the same, so we in the above-mentioned three types of sorting data, you can not own implementation for the interface, a direct call to rank.

Sort Sort pack customizations

  Through the above description, we know that only the above three types of Go is to help us achieve good, that if we want to sort of structure, how to achieve it? Similarly, we only need to give the type of structure to be sort of their own definition of implementation for the interface on it. Let's look at a specific example:

func main() {
    a := personSlice{
        {
            Name: "AAA",
            Age:  55,
        },
        {
            Name: "BBB",
            Age:  22,
        },
        {
            Name: "CCC",
            Age:  0,
        },
        {
            Name: "DDD",
            Age:  22,
        },
        {
            Name: "EEE",
            Age:  11,
        },
    }
    sort.Sort(a)
    fmt.Println("Sort: ", a)
    sort.Stable (A)   // stable sort 
    fmt.Println ( " Stable: " , A)
}
Custom Ordering example

How to choose the most appropriate package Sort Sort

  It says we do not care what sort sort using a sort, but what is sort Sort according to select it? Implement a package that comes in the sort ordering, we see that the above types are by sort.Sort (), further calling Sort (p) to sort, then we look at Sort (p) used ordering policy:

// sort.go
//
Sort sorts data. // It makes one call to data.Len to determine n, and O(n*log(n)) calls to // data.Less and data.Swap. The sort is not guaranteed to be stable. func Sort(data Interface) { n: = data.Len () quickSort(data, 0, n, maxDepth(n)) }

  Sort function parameters can be seen as the interface type, indicating that can pass any type of argument; then call quickSort sort function, which parameters maxDepth (n) Why? We look at:

// sort.go
// maxDepth returns a threshold at which quicksort should switch
// to heapsort. It returns 2*ceil(lg(n+1)).
func maxDepth(n int) int {
    var depth int
    for i := n; i > 0; i >>= 1 {
        depth++
    }
    return depth * 2
}

  Notes tells us that this function returns a threshold is used to distinguish or sort a row with a fast reactor. Then we go back and look at quickSort is how to distinguish according to this threshold:

// sort.go
func quickSort(data Interface, a, b, maxDepth int) {
    for b-a > 12 { // Use ShellSort for slices <= 12 elements
        if maxDepth == 0 {
            heapSort(data, a, b)
            return
        }
        maxDepth--
        mlo, mhi := doPivot(data, a, b)
        // Avoiding recursion on the larger subproblem guarantees
        // a stack depth of at most lg(b-a).
        if mlo-a < b-mhi {
            quickSort(data, a, mlo, maxDepth)
            to = am // ie, quickSort (data, race, b) 
        } Else {
            quickSort(data, mhi, b, maxDepth)
            b = mlo // i.e., quickSort(data, a, mlo)
        }
    }
    if b-a > 1 {
        // Do ShellSort pass with gap 6
        // It could be written in this simplified form cause b-a <= 12
        for i := a + 6; i < b; i++ {
            if data.Less(i, i-6) {
                data.Swap(i, i-6)
            }
        }
        insertionSort(data, a, b)
    }
}

  The code can be seen from the above logic, when the number of (ba) is larger than the element 12, with quick row (selection algorithm to select optimized values ​​of the hub), when using heap sort maxDepth == 0 (here not very understanding);

When the number of (ba) is greater than 1 and less than or equal element 12, first, a step == Hill sorting 6, followed by insertion sort.

Guess you like

Origin www.cnblogs.com/zpcoding/p/12037464.html