美文网首页
快速排序算法

快速排序算法

作者: Robin92 | 来源:发表于2019-07-29 00:57 被阅读0次

原理

快速排序算法基于这样一个理念:随机从中选一个值作为参考值,将它与全序列比较,比它小的放左边,大的放右边。这样完成一次排序,就会把整个序列分成两部分,再分别对这两部分排序即可。
复杂度 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. 先完成一次排序

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

  • 要有一个额外的空间来记标记选用的参考值(存下标);(需要把直接用下标的思想拆出来)
  • 用下标标记“始”与“终”;
    考虑的这些量先做为参数传入函数,之后再做精化处理。
    由于我们用 Go 语言对于数组只要不超出容量,可以认为是引用传递,且支持多重赋值,那么写下来如下:
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
}

相关文章

网友评论

      本文标题:快速排序算法

      本文链接:https://www.haomeiwen.com/subject/mximrctx.html