python算法-快速排序

快速排序:

学习快速排序,要先复习下递归:

递归的2个条件:

1. 函数自己调用自己

2.有一个退出的条件

练习:基于递归下一个函数,计算n!并且求出当n等于10的值。

n!=n * n-1*…..*1

#enconding = utf-8

def func(n):

if n<=1:

return 1

else:

return n*func(n-1)

print func(10)

结果:3628800

快速排序:也是基于递归的思想

核心思想:对于一个数组 12  23  3  4  56  21

快排是从里面随机选择一个数,如21,把所有小于这个数字的排在它的左边,把所有大于它的数排在右边。

用指针指明位置,遍历数组:j-> 0到4

用i表示下标i左边的都是小于21的,包括下标i

初始值 i=-1   -1是针对最小数刚好在最后一位的极端情况

初始值j=0 ,j控制遍历数组的下标。

用j去和21比较,如果大于21,则空过不处理;如果小于21:i要加1,把i和j指向的元素交换位置

手工排序:

i=-1  j=0

取出12,12<21-à i+1=0;i和j指向的元素交换位置,此时i=j=0,都是指向lista[0];j++

12  23  3  4  56  21

i=0,j=1

取出23,21  23>21,空过

12  23  3  4  56  21

i=0 ,j=2

取出3,21, 3<21->  i+1=1;i和j对应元素位置交换,lista[1],lista[2] =

12  3  23  4  56  21

i=1  j=3

取出4<21,i+1=2; i和j对应元素位置交换

12  3  4  23  56  21

i=1;j=4

取出56>21;空过

12  3  4  23  56  21

把下标i+1的元素和最后一个元素交换位置

12  3  4  21   56  23

这样,就完成了第一轮的排序。

为什么要选择最后一个数字呢?

很容易找到。其实选择哪一个最后的结果都是一样的。因此为了简单我们直接就取的最后一个数作为基准数字。

下面,我们来写出12  3  4 以及右子列表56  23快排一次后的结果

左: 3  4  12

右:23  56

快排程序:

1.对于listx调用快排

2.对于listx的左子列表12  3  4进行快排,对于listx的右子列表56  23进行快排

3.直到列表只有一个元素的时候,退出

#enconding = utf-8

def Quick_Sort(lista):

def pathSort(lista,sIndex,eIndex):#第一重排序

flag = lista[eIndex]

i = sIndex - 1

for j in xrange(sIndex,eIndex):

if lista[j]<flag:

i+=1

lista[i],lista[j] = lista[j],lista[i]

else:

pass

lista[eIndex],lista[i+1] = lista[i+1],lista[eIndex]

return i+1

def qSort(listb,sIndex,eIndex):

if sIndex >= eIndex: #如果开始位置大于等于起始位置,返回

return

middle = pathSort(listb,sIndex,eIndex)

#递归调用左子列表

qSort(listb,sIndex,middle-1)

#递归调用右子列表

qSort(listb,middle+1,eIndex)

qSort(lista,0,len(lista)-1)

return lista

if __name__ == ‘__main__‘:

print Quick_Sort([12,3,4,21,56,23])

变形练习1:修改成从大到小排列。

#enconding = utf-8

def Quick_Sort(lista):

def pathSort(lista,sIndex,eIndex):#第一重排序

flag = lista[eIndex]

i = sIndex - 1

for j in xrange(sIndex,eIndex):

if lista[j]>flag:

i+=1

lista[i],lista[j] = lista[j],lista[i]

else:

pass

lista[eIndex],lista[i+1] = lista[i+1],lista[eIndex]

return i+1

def qSort(listb,sIndex,eIndex):

if sIndex >= eIndex: #如果开始位置大于等于起始位置,返回

return

middle = pathSort(listb,sIndex,eIndex)

#递归调用左子列表

qSort(listb,sIndex,middle-1)

#递归调用右子列表

qSort(listb,middle+1,eIndex)

qSort(lista,0,len(lista)-1)

return lista

if __name__ == ‘__main__‘:

print Quick_Sort([12,3,4,21,56,23])

 

 

时间复杂度:

第一轮:做完快排后发现基准数是最大的一个,我们比较了n-1次,最后一个

第二轮:n-2次

第三轮:n-3次

第n-1轮:1次

1+2+3….+n-1 = n^2/2

时间复杂度为O(nlogn)

平均情况:

n

第一轮:n-1,排列出2个列表,确定了1个结点的位置

第二轮:n-3,排列出4个列表,确定了3个结点的位置

第三轮:n-7,排列出8个列表,确定了7个结点的位置

第四轮:n-15,排列 出16个列表,确定了15个结点的位置

…..

平均比较次数n-x

2^i-1

总共需要多少轮,才能完成快排?

2^1 + 2^2 +…..2^i-I = n

2*(1-2^i)/1 -2 –I =n

2^(i+1)-2-I =n

i+1 ~ logn

I ~ logn

log(n-x)

最终时间复杂度为 O(nlogn)

原文地址:https://www.cnblogs.com/qingqing-919/p/8440770.html

时间: 2024-08-11 13:37:55

python算法-快速排序的相关文章

python算法——快速排序算法

归并排序 1 def merge(li, low,mid, high): 2 i = low 3 j = mid+1 4 ltmp = [] 5 while i<=mid and j <=high: 6 if li[i]<li[j]: 7 ltmp.append(li[i]) 8 i += 1 9 else: 10 ltmp.append(li[j]) 11 j += 1 12 while i<=mid: 13 ltmp.append(li[i]) 14 i += 1 15 whi

python实现快速排序算法(两种不同实现方式)

# -*- coding: utf-8 -*- """ Created on Fri May 16 17:24:05 2014 @author: lifeix """ #快速排序 import sys import random length = 30 def qsort(arr,left,right): lp = left rp = right if lp == rp:return while True: while arr[lp] >=

python 算法

在Python实践中,我们往往遇到排序问题,比如在对搜索结果打分的排序(没有排序就没有Google等搜索引擎的存在),当然,这样的例子数不胜数.<数据结构>也会花大量篇幅讲解排序.之前一段时间,由于需要,我复习了一下排序算法,并用Python实现了各种排序算法,放在这里作为参考. 最简单的排序有三种:插入排序,选择排序和冒泡排序.这三种排序比较简单,它们的平均时间复杂度均为O(n^2),在这里对原理就不加赘述了.贴出来源代码. 插入排序: def insertion_sort(sort_lis

Python算法:推导、递归和规约

Python算法:推导.递归和规约 注:本节中我给定下面三个重要词汇的中文翻译分别是:Induction(推导).Recursion(递归)和Reduction(规约) 本节主要介绍算法设计的三个核心知识:Induction(推导).Recursion(递归)和Reduction(规约),这是原书的重点和难点部分 正如标题所示,本节主要介绍下面三部分内容: • Reduction means transforming one problem to another. We normally red

Python与快速排序

这个算法系列主要是自己学习算法过程中动手实践一下,写这个文章作为笔记和分享个人心得,如有错误请各位提出. 注:转载请说明出处 问题提出: 将以下数据升序排列:5, 2, 8, 6, 4, 9, 7, 3, 1 快速排序的原理: 快速排序的核心思想是(如下图) 1.先确定一个基准数,让后按照比较规则,如本例是升序排列,则将比基数大的放到右边,比基数小的放到左边. 2.接下来各边重复步骤1,直到全部排序完毕. 程序设计的思路就是(以上面的问题为例) 左右分别遍历比较 1 #非程序代码,只用来讲解 2

编程算法 - 快速排序算法 代码(C)

快速排序算法 代码(C) 本文地址: http://blog.csdn.net/caroline_wendy 经典的快速排序算法, 作为一个编程者, 任何时候都要完整的手写. 代码: /* * main.cpp * * Created on: 2014.6.12 * Author: Spike */ /*eclipse cdt, gcc 4.8.1*/ #include <stdio.h> #include <stdlib.h> int RandomInRange(int min,

Java算法快速排序

快速排序的原理:每次将序列以一个值为界限分成两组,在将两个序列分别以一个界限分成两组这样一直分下去. int[] a = {11,222,44,63,84,11,24,53,123,25,98,76,34}; 第一步:以34将数组a分成两组  11, 25, 24, 11              34,  63, 44, 53, 123, 222, 98, 76, 84 第二步:以11将11, 25, 24, 11分为两组  11, 11,     24, 25.以84将34,  63, 44

[硕.Love Python] QuickSort(快速排序)

def partition(a, i, j):     k = -1     while True:         while k * (a[i] - a[j]) >= 0:             if i == j:                  return i             j += k         a[i], a[j] = a[j], a[i]         i, j, k = j, i - k, -k def qsort(a, i, j):     if i <

重点算法--快速排序

#include<iostream> using namespace std; ////写出快速排序,归并排序与堆排序 int adjustarray(int a[],int left,int right) { int x = a[left]; while(left < right) { while(a[right] > x && left < right) right--; ///注意这个小于的范围 if(left < right ) {a[left]