算法导论之快速排序

快速排序

个人思绪很混乱, 建议直接看原文

简洁版:

def PARTITION(A, p, r):
    x = A[r] # 锚点 主元{大于它放一边,小于的放另一边}
    i = p - 1
    for j in range(p, r):
        if A[j] <= x:
            i += 1
            A[i], A[j] = A[j], A[i]
    A[i+1], A[r] = A[r], A[i+1]
    return i + 1

def QUICKSORT(A, p, r):
    if p < r: #分治
        q = PARTITION(A, p, r)
        QUICKSORT(A, p, q-1)
        QUICKSORT(A, q+1, r)

注释版:

import random

def PARTITION(A, p, r):
    x = A[r] # 锚点 主元{大于它放一边,小于的放另一边}
    i = p - 1
    for j in range(p, r):
        if A[j] <= x:
            i += 1
            A[i], A[j] = A[j], A[i]
    A[i+1], A[r] = A[r], A[i+1]
    return i + 1
"""partition函数体解析:
1. 将列表, 首元素下标, 尾元素下标传递进来
2. 设定基准值为尾元素
3. 遍历列表, 将列表内的每一项与基准值比较
4.  1. 如果当前元素小于基准值, 用指针记录下标
    2. 如果当前元素大于基准值, 过
    3. 如果当前元素小于基准值, 将指针后移一位, 将当前元素与指针现在所指的元素, 交换位置
5. 循环结束, 列表遍历完毕, 当前指针左侧的元素都比基准值小, 右侧的元素都比基准值大, 将基准值插入到此指针的位置
"""

"""
循环内部两个指针的解析:
1. 将尾元素设定为基准值
2. i指针默认设定的是j-1, 即: -1
3. j指针是根据循环的次数而变化, 从0到尾元素的下标
4. 1. 如果从开始遍历, 每一个元素都比基准值小的话, i指针只是记录了这些元素的位置,
      并一直向后移动, i指针走过的位置, 都为小于基准值的元素
   2. 接着往后遍历, 如果j指针指向的元素大于基准值, 直接跳过
   3. 接着往后遍历, 如果j指针指向的元素小于基准值, 停下,
      i指针还是停留在上一个比基准值小的元素的位置, 将i指针后移, i指向第一个比基准值大的元素, 将这个元素与j指向的元素交换位置
5. 1. 如果j指针指向的元素, 比基准值大, 过, i的值不变
   2. 如果j指针指向的元素, 比基准值小, i指针后移一位, 将i指针指向的元素与j指针指向的元素, 交换位置
6. 循环结束, 列表已遍历一遍, i指针左侧的元素都比基准值小, 右侧的元素都比基准值大, 将基准值插入到i指针位置处
"""

def QUICKSORT(A, p, r):
    if p < r: #分治
        q = PARTITION(A, p, r)
        QUICKSORT(A, p, q-1)
        QUICKSORT(A, q+1, r)

"""QuickSort()函数体解析
1. 将传递进来的列表进行partition()函数分割,
2. 分割为左列表[都比基准值小], 右列表[都比基准值大], 递归调用自己, 直到被分成n个列表长度为一的小列表
3. 结束第二步, 就代表列表排序完毕
"""

if __name__ == "__main__":
    A = [i for i in range(1, 1000)]
    random.shuffle(A)
    print("洗牌之后的列表:" + str(A))
    QUICKSORT(A, 0, len(A)-1)
    print("快排之后的列表:" + str(A))

原文地址:https://www.cnblogs.com/amou/p/9053928.html

时间: 2024-08-29 18:35:50

算法导论之快速排序的相关文章

算法导论:快速排序

快速排序是基于分治策略的.对一个子数组A[p…r]快速排序的分治过程的三个步骤为: 分解: 数组A[p…r]被划分成两个(可能空)子数组A[p…q-1]和A[q+1…r],使得A[p…q-1]中的每个元素都小于等于A[q],且小于等于A[q+1…r]中的元素.下标q也在这个划分过程中进行计算. 解决: 通过递归调用快速排序,对子数组A[p…q-1]和A[q+1…r]排序. 合并: 因为两个子数组就是原地排序的,将它们的合并不需要操作:整个数组A[p…r]已排序. 伪代码 算法的关键是求q的par

算法导论:快速排序和插入排序

代码实现 1 #ifndef _SORT_H 2 #define _SORT_H 3 4 // goal: quicksort and insertsort 5 // time: 12/2/2014 6 // author: zrss 7 // reference: introduction to algorithms 8 9 class Sort { 10 public: 11 void quickSort(int A[], int p, int r); 12 void insertSort(

[算法导论]quicksort algorithm @ Python

算法导论上面快速排序的实现. 代码: def partition(array, left, right): i = left-1 for j in range(left, right): if array[j] <= array[right]: i += 1 array[j], array[i] = array[i], array[j] array[i+1], array[right] = array[right], array[i+1] return i+1 def quicksort(arr

算法导论之七(中位数和顺序统计量之选择算法)

实际生活中,我们经常会遇到这类问题:在一个集合,谁是最大的元素?谁是最小的元素?或者谁是第二小的元素?....等等.那么如何在较短的时间内解决这类问题,就是本文要阐述的. 先来熟悉几个概念: 1.顺序统计量: 在一个由n个元素组成的集合中,第i个顺序统计量(order statistic)是该集合中第i小的元素.最小值是第1个顺序统计量(i=1),最大值是第n个顺序统计量(i=n).   2.中位数: 一个中位数是它所属集合的"中点元素",当n为奇数时,中位数是唯一的,位于i=(n+1

算法导论4:快速排序 2016.1.4

今天上最后一节史纲课,老师说不管什么学科,最重要的就是思想.我觉得很有道理. 好吧,不扯了.原谅我看书选择了速读策略,中间有很多感觉目前还很难看懂,以后有时间再细细学习.把略过去的在这里记一下. 一.矩阵乘法算法.复杂度从n^3优化到了n^2.81 (数字比较神奇).因为还没学线性代数,所以以后学了再看. 二.递归复杂度的计算和估计.这部分看起来有些复杂,好像需要比较高的数学水平,有空研究一下. 三.堆排序.这个以前已经写过了.http://www.cnblogs.com/itlqs/p/475

算法导论第七章快速排序

一.快速排序概述 关于快速排序,我之前写过两篇文章,一篇是写VC库中的快排函数,另一篇是写了快排的三种实现方法.现在再一次看算法导论,发现对快速排序又有了些新的认识,总结如下: (1).快速排序最坏情况下的时间复杂度为O(n^2),虽然最坏情况下性能较差,但快排在实际应用中是最佳选择.原因在于:其平均性能较好,为O(nlgn),且O(nlgn)记号中的常数因子较小,而且是稳定排序. (2).快速排序的思想和合并排序一样,即分治.快排排序的分治思想体现在: a.首先从待排序的数中选择一个作为基数,

快速排序的算法导论划分形式和hoare划分

1. hoare划分 1 int hoare_partition(int a[], int begin, int end) 2 { 3 int pivot = a[begin]; 4 int ini = begin; 5 int ter = end; 6 while (ini < ter) 7 { 8 while (a[ini] <= pivot && ini <end) 9 ++ini; 10 while (a[ter] >= pivot && t

快速排序之算法导论实现

#include <iostream> using namespace std; int partition(int *a,int p,int r) { int x=a[r]; int i=p-1;//note i important which is used for //storage the number smaller than flag x=a[r] for (int j=p;j<r;j++) { if (a[j]<x)// if a[j] smaller than x=

快速排序实现代码 算法导论7.1 7.2 7.4

快速排序通常是实际排序中应用最好的选择,因为平均性能很好,且是原址排序,不稳定. 书上的大部分内容在分析其运行时间,感觉看一下就好了(还是蛮喜欢数学的,可是...) #include <iostream> #include <algorithm> #include <random> using namespace std; //实际应用比较多,原址排序 typedef int index; index Partition(int *a, index p, index r