快排-Python实现

什么是快速排序

同冒泡排序(上篇博文)一样,快速排序也属于交换排序,通过元素之间的比较交换位置来达到排序的目的。

不同的是,冒泡排序在每一轮中只是把1个元素冒泡到数组的一端,而快速排序是:每一轮挑选一个基准元素,让比基准元素大的元素移动到数组的一边,比基准元素小的移动到数组的另外一端,从而把数组拆解成两部分。

举例说明一下,假设有如下的数组:

58639
第一轮:

1.设定基准元素: 假设以第一个元素5为基准元素

58639

2.比较: 蓝色元素为比基准元素5大的元素,绿色的为比基准元素小的元素。

58639

3.交换位置: 默认升序,比基准元素大的放左边,比基准元素小的放右边

35869

第一轮分析:

第一轮以基准元素5为界,将数组分为比5小的子集(A),和比5大的子集(B),所以接下来继续按照这样的步骤将A、B两部分子集排好就好了!!
子集A:

3

基准元素:

5

子集B:

869
第二轮:

由于子集A只有一个元素,不用再排序了,子集B有三个元素,接着用上面的步骤排序:

1.设定基准元素: 假设以第一个元素8为基准元素

869

2.比较: 蓝色元素为比基准元素8大的元素,绿色的为比基准元素小的元素。

869

3.交换位置: 默认升序,比基准元素大的放左边,比基准元素小的放右边

689

第二轮分析:

由于子集A只用一个元素,不用再做排序,故第二轮主要是对子集B做排序,排序结果如上图,子集B排序后,左右元素各一个,也不用再做排序,故到此为止!!!

算法复杂度

通过上面的举例可以看出,快速排序采用的是分治法的思想,这种思想的好处是什么呢?

假如我们有8个元素的数组,如果用冒泡排序的话,需要比较7轮,每一轮的把一个元素移动到数组的一端,这样的时间复杂度是O(n^2)。

而快排采用分治的思想,初始数组在每一轮都被拆成两部分,每一部分在下一轮又分别被拆成两部分,直到不可拆为止,拆分方式就如二叉树一般。

每一轮的比较和交换,需要把数组的全部元素都遍历一遍,时间复杂度是O(n),而大约需要logn轮(默认以2为底),因此快速排序算法的平均时间复杂度是O(nlogn)

代码实现(递归)

class Solution:
	def quick_sort(self,data):    
	    if len(data) >= 2:           # 如果数组长度大于等于2,则进行比较     
	        pivot = data[0]          # 选取第一个元素为基准,当然随机选取最好
	        left, right = [], []     # 定义基准值左右两侧的列表        
	        data.remove(pivot)       # 从初始数组中移除基准值        
	        for i in data:           # 遍历       
	            if i >= pivot:       # 大于基准值的元素,放进right数组中          
	                right.append(i)            
	            else:                
	                left.append(i)   # 小于基准值的元素,放进left数组中     
	        return quick_sort(left) + [pivot] + quick_sort(right)      # 递归   
	    else:        
	        return data
if __name__== "__main__":

#验证
solution = Solution()
test = [5,8,6,3,9,2,1,7]
solution.quick_sort(test )

输出:
[1, 2, 3, 5, 6, 7, 8, 9]

代码实现(非递归)

按照算法导论中的思想:

# 算法导论里的思想,i表示[l,i]都比pivot小的元素下标, j 依次遍历元素
def quick_sort_other(array, left, right):   
    if left >= right:    
        return array
    stack = [left,right]     
    while stack:
        low = stack.pop(0)
        high = stack.pop(0)
        if high <= low:
            continue
        pivot = array[high]
        i = low - 1 
        for j in range(low,high+1):
            if array[j] <= pivot:
                i += 1
                array[i],array[j] = array[j],array[i]
        stack.extend([low, i-1, i + 1, high])
    return array

验证

输入:
array = [6,1,4,2,3,9,5]
quick_sort_other(array,0,len(array)-1)
输出:
[1, 2, 3, 4, 5, 6, 9]
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值