首页 数组排序-快速排序
文章
取消

数组排序-快速排序

快速排序采用分治的思想,选择一个数为基数(如第一个数),遍历数组将大于基数的元素放在基数右侧,将小于基数的元素放在基数左侧,再将基数两侧的子数组按同样方法处理,依样重复处理直到子数组不能再分,最后就能得到一个升序的数组。

快速排序,最佳时间复杂度为 \(O(nlogn)\),最差时间复杂度为 \(O(n^2)\)。,平均时间复杂度为 \(O(nlogn)\)。

不难看出,基本思路是划分子数组+递归,示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// 快速升序排序
func quickSort(data *[]int, l, r int) {
	if l >= r {
		return
	}
	// 找到划分的基准数位置 i
	i := partition(data, l, r)

	// 对 i 前面的进行递归排序
	quickSort(data, l, i-1)
	// 对 i 后面的进行递归排序
	quickSort(data, i+1, r)
}

func partition(data *[]int, l, r int) int {
	i, j := l, r
	for i < j {
		// 将 data[l] 作为基准数
		for i < j && (*data)[j] >= (*data)[l] {
			j--
		}
		for i < j && (*data)[i] <= (*data)[l] {
			i++
		}
		// 此时,data[i] > data[l] > data[j],需要交换data[i]和data[j],使  data[i] < data[l]< data[j]
		(*data)[i], (*data)[j] = (*data)[j], (*data)[i]
	}
    // 将基准数放到分界位置 i
	(*data)[l], (*data)[i] = (*data)[i], (*data)[l]
	return i
}

func main() {
	var l = []int{10, 15, 3, 6, 7, 12, 2}
	fmt.Println("original:", l)
	quickSort(&l, 0, len(l)-1)
	fmt.Println("asc result:", l)
}

输出:

1
2
original: [10 15 3 6 7 12 2]
asc: [2 3 6 7 10 12 15]

如果要实现倒序排序,只需修改 partition 函数的 j--,i++ 条件即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
func partition(data *[]int, l, r int) int {
	i, j := l, r
	for i < j {
		// 将 data[l] 作为基准数
		for i < j && (*data)[j] <= (*data)[l] {
			j--
		}
		for i < j && (*data)[i] >= (*data)[l] {
			i++
		}
		// 此时,data[i] < data[l]< data[j],需要交换data[i]和data[j],使  data[i] > data[l]> data[j]
		(*data)[i], (*data)[j] = (*data)[j], (*data)[i]
	}
	(*data)[l], (*data)[i] = (*data)[i], (*data)[l]
	return i
}
本文由作者按照 CC BY 4.0 进行授权