pythonsort函数和快排哪个快_Python快速排序,python,之,QuickSort

介绍

快速排序同冒泡排序一样,也是属于交换排序,

通过比较并交换元素位置来达到排序的最终效果

但不同的是,冒泡排序只是把其中选择出来的1个元素交换到数列的一侧

快速排序是在每一轮的交换比较过程中,每次选择一个基准元素,把数列当中比基准元素

的元素移动到它的一侧,比基准元素

的元素移动到它的另外一侧,循环往复最终排好顺序

快速排序总体的平均时间复杂度是在

O(nlogn)

但是在最坏的情况下依然有

O(n^2)

的可能

快速排序的一个很重要的核心问题就是

基数的选择

那么基数的选择一共有两种方式:

1、可以将数列的首个元素作为基数;

2、也可以随机的选取一个数列当中的元素作为基数

基数选择好之后就看具体实现的方法了,实现的方法有两种:

1、双边循环

2、单边循环

一、双边循环

举一个简单的例子:

用随机生成的列表:

[17, 14, 30, 8, 20, 2, 8, 23]

在这个列表当中用下标为0的元素作为

基数pivot

,也就是

17

,在最左右两侧各设置一个指针,分别为

left,right

下面来实现第一轮,第一次遍历

pivot

[

17

, 14, 30, 8, 20, 2, 8,

23

]

left

right

一开始,动right指针,让right指针所指的元素和pivot进行比较,如果大于等于pivot,那right指针就向左移动一位;如果小于pivot,则right指针停止,切换到left指针

在当前的列表中23>17,则向左移动,比较之后发现8<17,则right指针指向8,停止

pivot

[

17

, 14, 30, 8, 20, 2, 8,

23

]

left

right

此时,轮到left指针,让left指针指向的元素和pivot进行比较,如果小于等于pivot,则left指针向右移动;如果大于pivot,则指针停止,一开始的left和pivot是一个元素,所以值相等,left向右移动一位,指向14,发现14小于17

pivot

[

17

,

14

, 30, 8, 20, 2, 8,

23

]

left

right

那么left指针向右再移动一位,到30,发现17<30,则left指针停止

pivot

[

17

,

14

, 30, 8, 20, 2, 8,

23

]

left

right

停止之后,交换left和right指针所指向的对应的值,

pivot

[

17

,

14

,

8

, 8, 20, 2,

30

,

23

]

left

right

发生数组元素的交换之后,开始第一轮,第二次的遍历

依旧从right指针开始,由于right指向的值是30>17,所以right指针向左移动

pivot

[

17

,

14

,

8

, 8, 20, 2,

30

,

23

]

left

right

当right 指向到2之后,2<17,right指针停止,此时轮到left指针,由于8<17,所以右移一位

pivot

[

17

,

14

,

8

,

8

, 20, 2,

30

,

23

]

left

right

但此时,当前left指向的值8,依然小于17,所以left指针继续右移

pivot

[

17

,

14

,

8

,

8

, 20, 2,

30

,

23

]

left

right

此时left指向的20是大于pivot的,left指针停止,停止之后,left和right指针各自指向的值,发生交换

pivot

[

17

,

14

,

8

,

8

,

2

,

20

,

30

,

23

]

left

right

发生交换之后开始第一轮,第三次遍历

重新回到right指针,20<17,right指针向左移动。此时,right和left重合

pivot

[

17

,

14

,

8

,

8

,

2

,

20

,

30

,

23

]

left

right

重合之后,将pivot的元素和left、right指针重合的元素进行交换

pivot

[

2

,

14

,

8

,

8

,

17

,

20

,

30

,

23

]

left

right

交换元素之后,第一轮遍历完成,开始下一轮的遍历,之后同理

二、代码实现

def quick_sort_use(startIndex, endIndex, randomList):

'''

快速排序双向循环

:param startIndex: 开始位置下标

:param endIndex: 结束位置下标

:param randomList: 创建的用于排序的随机数组

:return: 左右指针

'''

# 选择列表当中第一个元素作为基数

choose_pivot = randomList[startIndex]

# 确定left指针

left_pointer = startIndex

# 确定right指针

right_pointer = endIndex

# 准备遍历

while left_pointer != right_pointer:

isRightExchange = True

# right指针的移动

if left_pointer < right_pointer and choose_pivot <= randomList[right_pointer]:

right_pointer -= 1

isRightExchange = False

isLeftExchange = True

# left指针移动

if left_pointer < right_pointer and choose_pivot >= randomList[left_pointer]:

left_pointer += 1

isLeftExchange = False

if isLeftExchange and isRightExchange and left_pointer < right_pointer:

randomList[left_pointer], randomList[right_pointer] = randomList[right_pointer], randomList[left_pointer]

# 左右指针重合之后,与pivot进行交换

randomList[startIndex] ,randomList[left_pointer] = randomList[left_pointer], choose_pivot

return left_pointer , right_pointer # 返回left指针, right指针

num_list = [27, 30, 24, 39, 25, 46, 26, 29, 20]

# 递归实现快排

def use_quickSort(startIndex, endIndex, randomList):

if startIndex >= endIndex:return

pivot = quick_sort_use(startIndex, endIndex, randomList)

use_quickSort(startIndex, pivot[0] - 1, randomList) # 左边

use_quickSort(pivot[1] + 1 ,endIndex, randomList) # 右边

# 调用快排

use_quickSort(0, len(num_list) - 1, num_list)

print('双边循环结果:\n%s'%num_list)

197a5a065a7da001fbc4f7aa9d0de84c.png

三、单边循环

单边循环,顾名思义从数列的一侧进行遍历

参考数列如下:

[15, 17, 10, 3, 6, 9, 10, 4]

首先,选中一个元素作为基数:

pivot

[

15

, 17, 10, 3, 6, 9, 10, 4]

再设置一个pointer指针,指向数列起始位置

pivot

[

15

, 17, 10, 3, 6, 9, 10, 4]

p

准备好之后,开始遍历

从基数的下一个元素开始遍历,

如果遍历到的元素大于基数,则接着向后遍历

如果遍历到的元素小于基数,则pointer指针向右移动一位,然后将遍历的元素,和移动pointer指针之后所指的元素进行交换

第一轮开始:

从15的下一个元素开始遍历,17大于15,因此接着向后遍历

pivot

[

15

,

17

, 10, 3, 6, 9, 10, 4]

p

遍历到10的时候,发现,10<15,此时pointer指针向右移动一位,指向17

pivot

[

15

,

17

,

10

, 3, 6, 9, 10, 4]

p

交换二者的位置

pivot

[

15

,

10

,

17

, 3, 6, 9, 10, 4]

p

完成交换之后接着向后遍历

发现3<15,此时pointer指针向右移动一位

pivot

[

15

,

10

,

17

,

3

, 6, 9, 10, 4]

p

交换二者位置

pivot

[

15

,

10

,

3

,

17

, 6, 9, 10, 4]

p

接着向后遍历,6<15,pointer指针随即向右移动一位

pivot

[

15

,

10

,

3

,

17

,

6

, 9, 10, 4]

p

开始交换

pivot

[

15

,

10

,

3

,

6

,

17

, 9, 10, 4]

p

交换之后接着遍历,9<17,pointer右移一位

pivot

[

15

,

10

,

3

,

6

,

17

,

9

, 10, 4]

p

开始交换

pivot

[

15

,

10

,

3

,

6

,

9

,

17

, 10, 4]

p

交换之后,继续遍历,后面同理,全部遍历完成之后的结果如下:

pivot

[

15

,

10

,

3

,

6

,

9

,

10

,

4

,

17

]

p

此时第一轮全部遍历完成,将pointer所指的元素和pivot互换

pivot

[

4

,

10

,

3

,

6

,

9

,

10

,

15

,

17

]

p

第一轮完成,分治法后,开始递归各自剩下的区域

四、单边循环代码

def unidirection_quick_sort(startIndex, endIndex, num_list):

'''

处理快排的单边循环

:param startIndex:开始位置下标

:param endIndex:结束位置下标

:param num_list:待排序的数组

:return:pointer指针

'''

pivot = num_list[startIndex]

pointer = startIndex

for i in range(startIndex + 1, endIndex + 1): # 循环遍历整个数列

if num_list[i] < pivot:

pointer += 1

num_list[i], num_list[pointer] = num_list[pointer], num_list[i]

# 一趟遍历完成之后,交换pointer指向的值和pivot

num_list[startIndex], num_list[pointer] = num_list[pointer], num_list[startIndex]

return pointer

同样递归实现方法的调用

quick_num = [15, 17, 10, 3, 6, 9, 10, 4]

use_unidirection_quick_sort(0, len(quick_num) - 1, quick_num)

print('单边循环结果:\n%s'%quick_num)

026fe61ff36fb21ed8494e064d818f01.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值