算法导论:快速排序

快速排序是基于分治策略的。对一个子数组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的partition过程,它实现子数组A[p,..,r]的原地址重排

伪代码

算法选取数组的右边界A[r]作为分裂元素

讲解

可以看出p-i部分的数都小于等于x,i+1--j部分的数都大于j

在(b)情况:i++,交换后A[i]的值小于等于x,而原始A[i]的值本身就是大于x的交换到j的位置当然也是大于x的

最后当j==r时候,i++后也需要进行交换,虽然A[i]大于x,当时A[r]的值是等于x。快排是:左边的是小于等于x,右边的大于x

partition函数

    public int partition(int [] A,int low ,int high){
        int x = A[high];
        int i = low - 1;
        for( int j = low;j<= high - 1;j++){
            if( A[j] <= x){
                i = i + 1;
                swap(A,i,j);
            }
        }
        i = i + 1;
        swap(A,i,high);
        return i;
    }

    public void swap(int[] array,int i,int j){
        int tmp = array[i];
        array[i] = array[j];
        array[j] = tmp;
    }

求划分id的partition函数的另外一种写法

核心思想:找到左侧较大的数a,找到右侧较大的数b,a、b交换,在下一次寻找,两个指针相遇时候结束

    public int Paratition(int[] A,int left ,int right){
        if(left> right)
            return -1;
        int i = left;
        int j = right;
        int mid = A[left];
        if(i<j){
            while(i<j){
                while(i<j && mid< A[j])
                    j--;
                if(i<j){
                    A[i] = A[j];
                    i++;
                }
                while(i<j && A[i]< mid)
                    i++;
                if(i<j){
                    A[j] = A[i];
                    j--;
                }
            }
            A[i] = mid;
        }
        return i;

    }

快排函数

    public void quickSort(int[] A,int left,int right){
        if(left>right)
            return;
        int id = partition(A,left,right);
        quickSort(A,left,id-1);
        quickSort(A,id+1,right);

    }

时间复杂度

最坏情况:O(N^2)

平均情况:O(NlogN)

时间: 2024-07-30 03:56:39

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

算法导论-快速排序

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

Algorithm: quick sort implemented in python 算法导论 快速排序

1 import random 2 3 def partition(A, lo, hi): 4 pivot_index = random.randint(lo, hi) 5 pivot = A[pivot_index] 6 A[pivot_index], A[hi] = A[hi], A[pivot_index] 7 store_index = lo 8 for i in range(lo, hi): 9 if A[i] < pivot: 10 A[i], A[store_index] = A[

算法导论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

算法导论第7章___快速排序

快速排序本质上是插入排序,但是它在这个基础上增强了算法. 下面我们来分析一下快速排序: 有了前面的分析基础,我们在来看排序算法也就容易多了. public class Quick_Sort { private void quick_Sort(int []A,int left,int right){ if(left<right){ //划区比较,这个partition 第一次!得到的就是我们刚才说的2. int partition=partition(A, left, right); //实现第一

算法导论 第7章 快速排序

快速排序在最坏情况下的时间复杂度为O(n^2),虽然在最坏情况下运行时间比较差,但是快速排序通常是用于排序的最佳选择,因为其平均性能相当好,期望的运行时间为O(nlgn),且在O(nlgn)的记号中隐含的常数因子很小. 快速排序和合并排序有相似之处,都是需要划分序列,在合并排序中,划分的过程很简单,直接选择元素序列的中间位划分位置,排序是在合并的过程中实现的,所以合并排序的合并过程很重要:相比合并排序,快速排序就没有合并的过程,只有划分,快速排序的划分过程很重要,排序是在划分的过程中实现的. /

算法导论——lec 07 快速排序

一. 快速排序的描述 1. 快速排序是一种原地排序的算法,最坏情况下的时间复杂度为Θ(n^2),期望的运行时间为Θ(n logn),且其中隐含的常数因子较小. 2. 快速排序分三个步骤: 分解:数组A[p...r]被划分成两个数组A[p...q-1]和A[q+1...r],使得A[p...q-1]中的元素都小于等于A[q],A[q+1...r]中的元素都大于等于A[q].下标q在这个划分过程中计算. 解决:递归调用快速排序,对子数组A[p...q-1]和A[q+1...r]进行排序. 合并:两个