快速排序算法

2019-07-29  本文已影响0人  Robin92

原理

快速排序算法基于这样一个理念:随机从中选一个值作为参考值,将它与全序列比较,比它小的放左边,大的放右边。这样完成一次排序,就会把整个序列分成两部分,再分别对这两部分排序即可。
复杂度 nLog(n)
但涉及到机器机械地执行,这里每一步的描述里都有限制。用程序的描述方法,则有以下限制:

编程思路

1. 先考虑终止条件(特殊情况)

也许你习惯于最后考虑终止条件,但这样不利于自己调试代码。

    if len(arr) < 2 {
        return
    }
    if len(arr) == 2 && arr[0] > arr[1] {
        arr[0], arr[1] = arr[1], arr[0]
        return
    }
2. 先完成一次排序

这里是主要逻辑,所以要用机器的思维拆解快速排序原理的每一步:

func quickSort(arr []int, tempIndex, startIndex, endIndex int) {
    if len(arr) < 2 {
        return
    }
    if len(arr) == 2 && arr[0] > arr[1] {
        arr[0], arr[1] = arr[1], arr[0]
        return
    }

    for startIndex <= endIndex { // attention: <=, not <
        if arr[startIndex] > arr[tempIndex] {
            arr[startIndex], arr[tempIndex] = arr[tempIndex], arr[startIndex]
        }
        startIndex++
    }
}
加入递归

加入递归时,最重要的是考虑下一次调用的参数的传递,但结合 Go 的切片的概念和特性我们发现会很方便,只需要传入子切片,只对子切片操作排序就可以了。参考值可以始终选用数组第一个元素。所以改为代码如下:

func quickSort(arr []int) {
    if len(arr) < 2 {
        return
    }

    if len(arr) == 2 && arr[0] > arr[1] {
        arr[0], arr[1] = arr[1], arr[0]
    }

    tempIndex := 0
    startIndex := 0
    endIndex := len(arr) - 1

    for startIndex <= endIndex {
        if arr[startIndex] < arr[tempIndex] {
            arr[startIndex], arr[tempIndex] = arr[tempIndex], arr[startIndex]
        }
        startIndex++
    }

    if tempIndex > 0 {
        quickSort(arr[0 : tempIndex-1])
    }
    if tempIndex < len(arr)-1 {
        quickSort(arr[tempIndex+1:])
    }
}

其中还有细节要把握,比如 <<= 不能出错 等。
以下是所有代码清单:

package main

import (
    "fmt"
    "os"
    "strconv"
)

func main() {
    inputs := os.Args[1:]
    nums := covertToInt(inputs)
    n := len(nums)
    fmt.Printf("Your input has %d integers\n", n)

    quickSort(nums)

    fmt.Println(nums)
}

func quickSort(arr []int) {
    if len(arr) < 2 {
        return
    }

    if len(arr) == 2 && arr[0] > arr[1] {
        arr[0], arr[1] = arr[1], arr[0]
    }

    tempIndex := 0
    startIndex := 0
    endIndex := len(arr) - 1

    for startIndex <= endIndex {
        if arr[startIndex] < arr[tempIndex] {
            arr[startIndex], arr[tempIndex] = arr[tempIndex], arr[startIndex]
        }
        startIndex++
    }

    if tempIndex > 0 {
        quickSort(arr[0 : tempIndex-1])
    }
    if tempIndex < len(arr)-1 {
        quickSort(arr[tempIndex+1:])
    }
}

func covertToInt(strs []string) []int {
    ints := []int{}
    for _, v := range strs {
        i, _ := strconv.Atoi(v)
        ints = append(ints, i)
    }
    return ints
}

上一篇 下一篇

猜你喜欢

热点阅读