15分钟写不出快速排序的不考虑?!
快排思想:
快速排序首先选取一个数组元素作为基准(pivot),将小于pivot的放在左边,把大于pivot的放在右边,分割成两部分。再对其左右两部分进行排序。快排使用二分的思想将一个串分成两个子串,具体步骤如下:
在数组中挑一个元素作为基准pivot;
分区操作:将所有小于基准值的元素放到基准前面,所有大于基准值的元素放到后面,相同元素放到任一边。操作完成后,基准位于数列的中间位置;
使用递归分别将小于基准和大于基准的子数组排序。
代码实现:
Python版
def quick_sort(nums):n = len(nums)def patition(left, right):if left >= right:return nums # 设置递归终止条件pivot = left # 先将最左元素初始化为基准i = leftj = rightwhile i < j:while i < j and nums[j] > nums[pivot]:j -= 1 # 右侧指针向前移动遍历while i < j and nums[i] <= nums[pivot]:i += 1 # 左侧指针向后移动遍历nums[i], nums[j] = nums[j], nums[i] # 指针指向的元素互换nums[pivot], nums[j] = nums[j], nums[pivot] # 交换基准元素patition(left, j - 1) # 递归基准左侧子串patition(j + 1, right) # 递归基准右侧子串return numsreturn patition(0, n-1)nums = [5, 4, 2, 3, 1]print(quick_sort(nums))# [1, 2, 3, 4, 5]
Golang版
package mainimport "fmt"func quickSort(nums[]int) []int {if len(nums) < 2{ //如果数字长度小于2直接返回return nums}else {pivot := nums[0] //将数组中第一个数初始化为基准var less []intvar greater []intfor _, value := range nums[1:]{ //从基准的下一位开始遍历if value <= pivot{less = append(less, value) //存放比基准值小的半区} else {greater = append(greater, value) //存放比基准值大的半区}}var res []int //存放排序后的结果集res = append(res, quickSort(less)...)res = append(res, pivot)res = append(res, quickSort(greater)...)return res}}func main() {nums := []int{0, 9, 8, 4, 1, 6, 5}res := quickSort(nums)fmt.Println(res)//[0 1 4 5 6 8 9]}
这里的 ‘...’ 是Golang的语法糖,如果不加三个点会有如下报错:
'...'有两种用法:
第一种是为了解决图中的问题,将slice打散进行传递,即将quickSort处理后的结果元素打散后一个个append进res数组中,使代码更加简洁。
第二种常用于函数有多个不定参数的情况,可以接受多个不确定数量的参数。
package mainimport "fmt"func test1(args ...string) { //可以接受任意个string参数for _, v := range args{fmt.Println(v)}}func main() {var res = []string{"abc","123","jkl","89ui",}test1(res...)}
本例中如果不加'...'也会有“Cannot use 'res' (type []string) as the type string”这样的报错。
