刨了快速排序

摘要:这篇文章概括的描述了常见排序法,然后对快速排序的思想以及代码实现进行了详细的解剖,最后推出一道排序的面试题

最近一直在鼓捣排序,今天撸一篇排序吧。

排序中比较常见的种类有:冒泡法排序;选择排序;插入排序,快速排序,归并排序

其中最常用到就是快速排序:

其主要思想:1.找一个标杆(或者你可以称之为标准)元素(通常默认选择序列中的第一个元素);

2. 遍历所有的元素和标杆进行比较,最后大于标杆的放在其右,小于标杆的放在其左边;

3.然后重复1和2 以此来达到排序目的

一趟快速排序:alist 是待排序的列表

1.标杆元素 mid = alist[0]

2 取两个游标(变量)low 和 high

low 指向 alist[0],low =alist[0]

high指向alist[len(alist)-1],high = alist[len(alist)-1]

比较high指向位置的值和mid的大小,如果alist[high] < mid 把alist[high] 赋值给alist[low],否则 high向后退1,即 high -= 1;

然后low指向的位置向前移动1,即 low += 1,继续比较此时alist[low] 和 mid 的大小

如果alist[low] > mid ,把alist[low]赋值给alist[high],然后high向后退1,否则low向前移动1

3 直到low == high  ,第一趟快排结束

真代码实现!

 1 def quick_sort(alist,start,end):
 2     if start >= end:
 3         return
 4     mid = alist[start]   #标杆元素
 5     low = start            #指向第一个元素的游标
 6     high = end             #指向最后一个元素的游标
 7     while low < high:
 8    #两个游标没有相遇执行此循环
 9         while low< high and alist[high]>= mid:
10            #high指向的元素大于mid标杆元素high向后退1
11             high -= 1
12         #把小于标杆元素的值赋给low指向的位置
13         alist[low] = alist[high]
14
15         while low < high and alist[low] < mid:
16             #low指向的元素小于 mid标杆元素 low向前进1
17             low += 1
18         #把大于标杆元素的值赋给high指向的位置
19         alist[high] = alist[low]
20     #low和high相遇跳出循环,并且把mid赋值给low指向的位置
21     alist[low] = mid
22
23      #把小于mid的序列重复进行以上操作
24      quick_sort(alist,start,low)
25      #把大于mid 的序列重复以上操作
26      quick_sort(alist,low+1,end)
27
28
29 if __name__ == ‘__main__‘:
30     alist = [1,5,3,44]
31     quick_sort(alist,0,len(alist)-1)
32     print(alist)
33
34       

面了个试:有两个序列a和b,大小都为n,

要求:交换a和b中的元素,使得a序列中的和 与b序列中的和之差最小。

思路:合并两个列表并排序,然后分别向两个空列表中追加元素,奇数位置的元素追加到列表1,偶数位置的追加到列表2

法1:合并之后排列用内建函数sort排列完成后追加元素

 1 def split_(alist):
 2     list1 = []
 3     list2 = []
 4     n = len(alist)
 5     for i in range(n):
 6         if i%2 ==0:
 7             list2.append(alist[i])
 8         else:
 9             list1.append(alist[i])
10
11     print(‘第一个列表:%s,第二个列表: %s‘%(str(list1),str(list2)))
12     return ‘两个列表差为:%d‘% abs(sum(list1) - sum(list2))
13
14 if __name__ == ‘__main__‘:
15
16     a= [220,343,44,3,34,46,55,1004]
17     b = [100,22,333,465,544,66,77,483]
18     a.extend(b)
19     a.sort()
20     print(split_(a))

上述的输出为:

第一个列表:[22, 44, 55, 77, 220, 343, 483, 1004],第二个列表: [3, 34, 46, 66, 100, 333, 465, 544]
两个列表差为:657

可能这个例子解法和快排没多大关系,但是如果限制内建函数的使用,那么我们可以先用快排,再取元素追加

时间: 2024-12-29 11:26:44

刨了快速排序的相关文章

快速排序

快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列. 快速排序是一种不稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动 快速排序是C.R.A.Hoare于1962年提出的一种划分交换排序.它采用了一种分治的策略,通常称其为分治法(Divide-and-ConquerMethod). 该方法的基本思想是:

快速排序——Python

快速排序: 在一组数据中选择一个基准值,让后将数据分为两个部分,一部分大于基准,一部分小于基准,然后按此方法将两个部分分组,直到不能再分为止. 需要明白一个概念递归和分而治之的概念. Python实现: 1 # 快速排序 2 3 import random 4 5 def quick_sort(arr): 6 # 边界条件 7 if len(arr) < 2: 8 return arr 9 key = random.choice(arr) # 选择基准 10 left = [i for i in

快速排序的实现(不保证效率

众所周知,快速排序的核心是分治的思想,选一个基准出来,然后通过划分操作,使得,该元素最终处于的位置的左边的元素都小于等于它,右边的元素都大于等于它 划分操作就是两次递归嘛,没什么的,关键在于不借助外部空间我们如何实现划分操作 首先我们不知道该元素放在哪里,显然这是最后才能确定的, 我了解到一种填坑法的实现... 那就是首先保存第一个位置的值,然后从后向前扫描第一个小于x的值,我们就可以直接覆盖第一个位置的值,然后我们再从前向后找大于x的值, 把后面的坑填上 下面枚举几种情况 基准前后有相同数量的

快速排序的总结

快速排序的思想是分而治之,利用递归达到快速排序的效果 首先要选定一个基准数,一般选择最左边的数为基准数,排序的目标就是让这个基准数的左边全小于这个基准数,右边全大于这个基准数.然后以这个基准数为分隔线,在左右两侧再次调用这个排序的函数,直到全部有序.简述过程: 以  8 9 4 7 2 6 首选 1. 选择两个哨兵 i,j 分别指向8,6,基准数为8 2.从j哨兵开始,因为j指向的6小于基准数8,不符合j指向的数都要大于8的要求,所以将j指向的数覆盖i指向的数,同时i指向的数变成9 6 9 4

[数据结构] 快速排序

基本思想 快速排序(Quicksort)是对冒泡排序的一种改进,又称划分交换排序(partition-exchange sort. 快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists). 步骤为: ①.从数列中挑出一个元素,称为"基准"(pivot) ②.重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边).在这个分区结束之后,该基准就处于数列的中间位置.这个称

使用JAVA直观感受快速排序与冒泡排序的性能差异

初学算法,肯定会编写排序算法 其中两个最为有名的就是冒泡排序和快速排序 理论上冒泡排序的时间复杂度为O(N^2),快速排序的时间复杂度为O(NlogN) 下面本门使用JAVA,分别编写三段排序程序 对十万个0-9999的整数进行一次冒泡排序 对十万个0-9999的整数进行1000次快速排序,使用递归完成 对十万个0-9999的整数进行1000次快速排序,使用堆栈完成 对十万个0-9999的整数进行一次冒泡排序: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

Swift实现的快速排序及sorted方法的对比

Swift语言有着优秀的函数式编程能力,面试的时候面试官都喜欢问我们快速排序,那么用Swift如何实现一个快速排序呢?首先扩展Array类: extension Array { var decompose : (head: T, tail: [T])? { return (count > 0) ? (self[0], Array(self[1..<count])) : nil } } 属性decompose的作用是返回数组中的第一个元素和剩下的元素,注意这个属性是可选型的,当count为0的时

Java实现排序算法之快速排序

一.综述 快速排序是交换排序中的一种,平均算法复杂度是O(nlogn),最坏O(n*n).下面用Java实现一个快速排序,并用注释的方式解释了思想和原理. 二.Java实现堆排序 三.结果检验 版权声明:本文为博主原创文章,未经博主允许不得转载.

单链表排序——快速排序实现

利用快速排序,同向一前一后两个指针 #ifndef LIST_H_ #define LIST_H_ #include <iostream> #include <utility> class List { private: struct ListNode { int _value; ListNode* _next; }; public: List(): _head(nullptr) {} ~List() { while (nullptr != _head) { auto tmp =