使用Python实现的4种快速排序算法
快速排序算法,总体来说就是选一个基准值,把小于基准值的分一拨,把大于基准值的分到另一拨,然后递归。
有区别的是,分区算法有差异,最直接的是,选个基准值,定义两个列表(小值分区less和大值分区great),然后挨个比较,小的追加到less,大的追加到great
再有就是,选个基准值,先从右边开始比,比基准值大的不管,比基准值小就和基准值换位置,换一次后,就去和左边比,比基准值小的不管,比基准值大的又去换位置,略有些绕。
最后,还可以不递归,通过把分区节点保存在栈里来实现。
1 # -*- coding: utf-8 -*-
2
3 import numpy as np
4 #1)依次对比arr[0]和其他元素,比arr[0]小的话,就原地删除,然后插入到arr[0]前面,基准值后移。大于等于,则不处理。然后递归
5 #原地排序
6 def quick_sort1(arr,left,right):
7
8 if left>=right:
9 return
10 flag=left
11 for i in range(left+1,right+1):
12 if arr[flag]>arr[i]:
13 temp=arr[i]
14 del arr[i]
15 arr.insert(flag,temp)
16 flag+=1
17 quick_sort1(arr,left,flag-1)
18 quick_sort1(arr,flag+1,right)
19 #2)基准值arr[0],对比所有元素,比它小就追加到less后面,比它大就追加到great后面,相等就追加到pivot后面,然后递归
20 #返回排序后的列表
21 def quick_sort2(arr):
22 less=[]
23 great=[]
24 pivot=[]
25 if len(arr)<=1:
26 return arr
27 else:
28 p=arr[0]
29 for i in arr:
30 if i<p:
31 less.append(i)
32 elif i>p:
33 great.append(i)
34 else:
35 pivot.append(i)
36 less=quick_sort2(less)
37 great=quick_sort2(great)
38 return less+pivot+great
39 #2-2)基本思想同上,代码更简化
40 def quick_sort22(arr):
41 if len(arr)<=1:
42 return arr
43 else:
44 return quick_sort22([i for i in arr[1:] if i<arr[0]])+[arr[0]]+quick_sort22([i for i in arr[1:] if i>=arr[0]])
46 #2-3)思路同上,更简化的版本
47 quick_sort23=lambda xs:((len(xs)<=1 and [xs]) or [quick_sort23([x for x in xs[1:] if x<xs[0]])+[xs[0]]+quick_sort23([x for x in xs[1:] if x>=xs[0]])])[0]
49 quick_sort24=lambda arr:arr if len(arr)<=1 else quick_sort24([x for x in arr[1:] if x<arr[0]])+[arr[0]]+quick_sort24([x for x in arr[1:] if x>=arr[0]])
#lambda 参数:取值1,如果满足条件1,否则,取值2
51
52
53 #3)定义两个函数:分区和排序。分区是要把列表元素移动位置,直到基准值arr[0]移到中间(左边都比它小,右边都比它大)。排序则调用分区并递归
54 #原地排序
55 def partition(arr,i,j):
56 p=arr[i]
57 while i!=j:
58 while i<j and p<=arr[j]:#此处添加=,解决了之前遇到的序列中有重复值时死循环的问题
59 j-=1
60 arr[i]=arr[j]
61 while i<j and p>arr[i]:
62 i+=1
63 arr[j]=arr[i]
64 arr[i]=p
65 return i
66 def quick_sort3(arr,i,j):
67 if i<j:
68 mid=partition(arr,i,j)
69 quick_sort3(arr,i,mid-1)
70 quick_sort3(arr,mid+1,j)
71 #3-2)上述思路的变体,分区函数变动,每次都比右边是否比基准值大,大的话,j前移,否则,把arr[j]给到arr[i],然后i后移,arr[i]再给到arr[j],继续上述循环
72 def partition2(arr,i,j):
73 p=arr[i]
74 while i!=j:
75 while i<j and p<=arr[j]:
76 j-=1
77
78 while i<j and p>arr[j]:
79 arr[i]=arr[j]
80 i+=1
81 arr[j]=arr[i]
82 arr[i]=p
83 return i
84 def quick_sort32(arr,i,j):
85 if i<j:
86 mid=partition2(arr,i,j)
87 quick_sort32(arr,i,mid-1)
88 quick_sort32(arr,mid+1,j)
89 #3-3)分区函数变动,基准值为最后一个值,依次比较,如果比基准值小,就换到前面去,最后再把基准值换到中间。
90 def partition3(arr,i,j):
91 p=arr[j]
92 x=i-1
93 for y in range(i,j):
94 if arr[y]<=p:
95 x+=1
96 arr[x],arr[y]=arr[y],arr[x]
97 arr[x+1],arr[j]=arr[j],arr[x+1]
98 return x+1
99 def quick_sort33(arr,i,j):
100 if i<j:
101 mid=partition3(arr,i,j)
102 quick_sort33(arr,i,mid-1)
103 quick_sort33(arr,mid+1,j)
104 #4)非递归方式,使用栈,思路类似previous,只是把切分边界保存在栈(用list实现)里,\
105 #当只剩一个元素时,跳出本次循环,进入下次循环,看下一个区间里元素值是否多于1个,直到栈空
106 def quick_sort4(arr,i,j):
107 if j<=i:
108 return
109 stack=[]
110 stack.extend([i,j])
111 while stack:
112 left=stack.pop(0)
113 right=stack.pop(0)
114 if right<=left:
115 continue
116 x=left-1
117 p=arr[right]
118 for y in range(left,right):#此处循环不包括最后一个元素,循环结束后,最后一个元素换到中间
119 if arr[y]<=p:
120 x+=1
121 arr[x],arr[y]=arr[y],arr[x]
122 arr[x+1],arr[right]=arr[right],arr[x+1]
123 stack.extend([left,x,x+2,right])
124
125
126 if __name__=="__main__":
127 s=np.random.randint(1,30,20).tolist()
128 print(s)
129 #print(quick_sort24(s))
130 quick_sort4(s,0,len(s)-1)
131 print(s)
使用Python实现的4种快速排序算法的更多相关文章
- python:实现几种排序算法
冒泡排序 比较相邻两个字符,如果左边大于右边,则交换位置,遍历一遍字符后,则最大的肯定在最右边:继续循环处理剩下的字符(最右边的不用再比较了,已经最大了) 代码实现: def BubbleSort(s ...
- python实现常用五种排序算法
一.冒泡排序 原理: 比较相邻的元素.如果第一个比第二个大就交换他们两个 每一对相邻元素做同样的工作,直到结尾最后一对 每个元素都重复以上步骤,除了最后一个 第一步: 将乱序中的最大值找出,逐一移到序 ...
- 几种排序算法的学习,利用Python和C实现
之前学过的都忘了,也没好好做过总结,现在总结一下. 时间复杂度和空间复杂度的概念: 1.空间复杂度:是程序运行所以需要的额外消耗存储空间,一般的递归算法就要有o(n)的空间复杂度了,简单说就是递归集算 ...
- python实现快速排序算法
快速排序算法又称划分交换排序(partition-exchange sort),一种排序算法,最早由东尼·霍尔提出.在平均状况下, 排序n个项目要O(nlogn)次比较.在最坏状况下则需要O(n*2) ...
- php四种基础算法:冒泡,选择,插入和快速排序法
转自:http://www.php100.com/html/php/rumen/2013/1029/6333.html 许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣.作为一 ...
- 10 种机器学习算法的要点(附 Python 和 R 代码)
本文由 伯乐在线 - Agatha 翻译,唐尤华 校稿.未经许可,禁止转载!英文出处:SUNIL RAY.欢迎加入翻译组. 前言 谷歌董事长施密特曾说过:虽然谷歌的无人驾驶汽车和机器人受到了许多媒体关 ...
- $用python实现快速排序算法
本文主要介绍用python实现基本的快速排序算法,体会一下python的快排代码可以写得多么简洁. 1. 三言两语概括算法核心思想 先从待排序的数组中找出一个数作为基准数(取第一个数即可),然后将原来 ...
- 10 种机器学习算法的要点(附 Python)(转载)
一.前言 谷歌董事长施密特曾说过:虽然谷歌的无人驾驶汽车和机器人受到了许多媒体关注,但是这家公司真正的未来在于机器学习,一种让计算机更聪明.更个性化的技术 也许我们生活在人类历史上最关键的时期:从使用 ...
- 机器学习10种经典算法的Python实现
广义来说,有三种机器学习算法 1. 监督式学习 工作机制:这个算法由一个目标变量或结果变量(或因变量)组成.这些变量由已知的一系列预示变量(自变量)预测而来.利用这一系列变量,我们生成一个将输入值映射 ...
随机推荐
- 个人项目(wc.exe)
一.项目在GitHub上的地址: ·https://github.com/DawsonHuang/Word_Count 二.项目描述: ·项目名:WordCount(以下简称WC或项目) ·项目简述: ...
- 半夜删你代码队 Day6冲刺
一.每日站立式会议 1.站立式会议 成员 昨日完成工作 今日计划工作 遇到的困难 陈惠霖 完成注册界面 好友界面 无 侯晓龙 了解数据库使用 帮助他人建立数据库 无 周楚池 完成登录界面+管理员界面初 ...
- AcWing 204. 表达整数的奇怪方式 / Strange Way To Express Integers
我作为一个初中蒟蒻,听y大视频听了5遍还不懂,快哭了.然后终于(好像)搞懂,写成题解加深一下记忆... 将式子等价转换 对于每两个式子(我们考虑将其合并): \(x \equiv a_1 \%\ m_ ...
- MySQL技术内幕InnoDB存储引擎(一)——MySQL体系结构和存储引擎
1.数据库和实例 数据库(database)和实例(instance)不能混淆. 什么是数据库 数据库是物理操作系统文件或其他文件类型的集合.说白了,就是存储着的文件,不会运行起来,只能被实例增删改查 ...
- Django认证系统并不鸡肋反而很重要
在使用django-admin startproject创建项目后,Django就默认安装了一个采用session实现的认证系统.这是Django相比于其他框架的一大特点:自带认证系统,开箱即用.有人 ...
- redis 常用基本命令
redis 常用基本命令 redis-cli 启动set 键 值 # 存储 单条数据 # set 'zsj' 'bab' get 键 # 通过键获取值 # get ...
- 一文入门Redis
一文入门Redis 目录 一文入门Redis 一.Redis简介 二.常用数据类型 1.String(字符串) 2.Hash(哈希) 3.List(列表) 4.Set(集合) 5.Zset(有序集合) ...
- 学好Spark/Kafka必须要掌握的Scala技术点(二)类、单例/伴生对象、继承和trait,模式匹配、样例类(case class)
3. 类.对象.继承和trait 3.1 类 3.1.1 类的定义 Scala中,可以在类中定义类.以在函数中定义函数.可以在类中定义object:可以在函数中定义类,类成员的缺省访问级别是:publ ...
- Happens-Before原则到底规定了什么
Happens-Before 规则 如何理解 Happens-Before 呢?如果望文生义(很多网文也都爱按字面意思翻译成"先行发生"),那就南辕北辙了,Happens-Befo ...
- js上 十二、函数初步-1
11-1.引入(认识函数) 引入: 说起函数,其实我们并不陌生,在初中数学中我们就接触过函数:例如我们所学的 y = 2X+1 ; 这是一个二元一次方程,也是我们数字中的函数: 当我们每次输入 ...