算法分析之——quick-sort快速排序

快速排序是一种排序算法,最坏情况运行时间为θ(n2),但其最佳期望运行时间为θ(nlgn),并且θ(nlgn)记号中隐含的常数因子很小,快排是在就地排序的一种排序算法。快排是基于分治思想的,与归并排序一样。快速排序是一种不稳定的排序算法,因为算法实现过程中涉及到元素交换。
思路:
(1)分解:数组A[n]被划分两个字数组A[0..q-1]和A[q+1..n],使得对于数组A[0..q-1]中的元素都小于A[q], A[q+1..n]中的元素都大于等于A[q]。此时A[q]就得排好序。
(2)解决:通过递归调用快速排序,对字数组A[0..q-1]和A[q+1..n]进行排序
(3)合并:因为两个字数组已经是就地排好序的了,整个数组已经排好序了。
void quicksort(int A[],int p,int r)
{
    int q;
    if(p<r)
    {
        q=partition(A,p,r);
        quicksort(A,p,q-1);
        quicksort(A,q+1,r);
    }
}
int partition(int A[],int p,int r)
{
    int x,i,j,middle;
    x = A[r];
    i = p-1;
    for(j=p;j<=r-1;j++)
    {
        if(A[j]<=x)
        {
            i++;
            middle=A[i];
            A[i]=A[j];
            A[j]=middle;

        }
    }
    middle=A[r];
    A[r]=A[i+1];
    A[i+1]=middle;
    return (i+1);
}

假设输入的数组为A[8]={2,8,7,1,3,5,6,4};下面来实现输入过程,length=8;main函数调用quicksort(A,0,length-1)即quicksort(A,0,7)。

此处举例一次快排的执行过程:

基准选择数组的最后一个元素A[r].

1.步骤7中for循环执行过程见下图:j<=r-1;即j<=6;x=4

(1)j从0到6进行循环:i=-1;j=0

判断if(A[j]<=x):A[j]=A[0]=2<4,执行

i++;

middle=A[i];

A[i]=A[j];

A[j]=middle;

即i=0;A[i]与A[j]交换;

(2)j从1到6进行循环:i=0;j=1

判断if(A[j]<=x):A[j]=A[1]=8>4;不满足。执行下一次for循环

(3)j从2到6进行循环:i=0;j=2

判断if(A[j]<=x):A[j]=A[2]=7>4;不满足。执行下一次for循环

(4)j从3到6进行循环:i=0;j=3

判断if(A[j]<=x):A[j]=A[3]=1<4;满足,执行i++;A[i]与A[j]交换;

i++;
middle=A[i];
A[i]=A[j];
A[j]=middle;

i=1;A[i]=A[1]=8;A[j]=A[3]=1;如下图

(5)j从4到6进行循环:i=1;j=4

判断if(A[j]<=x):A[j]=A[4]=3<4;满足,执行i++;A[i]与A[j]交换;

i=2;A[i]=A[2]=7;A[j]=A[4]=3;如下图:

(6)j从5到6进行循环:i=2;j=5

判断if(A[j]<=x):A[j]=A[5]=5>4;不满足。执行下一次for循环

(7))j从6到6进行循环:i=2;j=6

判断if(A[j]<=x):A[j]=A[6]=6>4;不满足。执行下一次for循环

(8)j++;j=7,跳出for循环。此时数组如下图:图a

2.接下来执行步骤8,执行完后如图b

返回i+1=3,即主元素的下标。

最后第一次递归执行的结果图如下:

下次递归,主元素不再进行排序,分别对其左边和右半边的数组进行排序。即2、1、3和7、5、6、8分别递归。此处不再一一举例。

最后给出程序运行的结果:

源代码下载地址源代码

时间: 2024-08-01 17:43:34

算法分析之——quick-sort快速排序的相关文章

Quick Sort(快速排序)

Quick Sort Let's arrange a deck of cards. Your task is to sort totally n cards. A card consists of a part of a suit (S, H, C or D) and an number. Write a program which sorts such cards based on the following pseudocode: Partition(A, p, r) 1 x = A[r]

快速排序(Quick Sort)的C语言实现

快速排序(Quick Sort)的基本思想是通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对着两部分记录继续进行排序,以达到整个序列有序,具体步骤为 设立枢轴,将比枢轴小的记录移到低端,比枢轴大的记录移到高端,直到low=high停止 分别对枢轴低高端部分再次快速排序(即重复第1步) 重复第1.2步,直到low=high停止 C语言实现(编译器Dev-c++5.4.0,源代码后缀.cpp) 原创文章,转载请注明来自钢铁侠Mac博客http:/

笔试算法题(54):快速排序实现之单向扫描、双向扫描(single-direction scanning, bidirectional scanning of Quick Sort)

议题:快速排序实现之一(单向遍历) 分析: 算法原理:主要由两部分组成,一部分是递归部分QuickSort,它将调用partition进行划分,并取得划分元素P,然后分别对P之前的部分和P 之后的部分递归调用QuickSort:另一部分是partition,选取划分元素P(随机选取数组中的一个元素,交换到数组末尾位置),定义两个标记 值left和right,随着划分的进行,这两个标记值将数组分成三部分,left之左的部分是小于划分元素P的值,left和right之间的部分是大 于等于划分元素P的

笔试算法题(55):快速排序实现之非递归实现,最小k值选择(non-recursive version, Minimal Kth Selection of Quick Sort)

议题:快速排序实现之五(非递归实现,短序列优先处理,减少递归栈大小) 分析: 算法原理:此算法实现适用于系统栈空间不足够快速排序递归调用的需求,从而使用非递归实现快速排序算法:使用显示下推栈存储快速排序中的每一次划分结果 (将left和right都压入堆栈),并且首先处理划分序列较短的子序列(也就是在得到一次划分的左右部分时,首先将长序列入栈,然后让段序列入栈), 这样可以保证当快速排序退化的线性效率的时候,栈大小仍旧在㏒N范围内.算法策略类似于最小子树优先遍历规则: 弱势:当序列已经就绪,每次

经典排序算法 - 快速排序Quick sort

经典排序算法 - 快速排序Quick sort 原理,通过一趟扫描将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 举个例子 如无序数组[6 2 4 1 5 9] a),先把第一项[6]取出来, 用[6]依次与其余项进行比较, 如果比[6]小就放[6]前边,2 4 1 5都比[6]小,所以全部放到[6]前边 如果比[6]大就放[6]后边,9比[6]大,放到[6

快速排序(Quick Sort)

快速排序是初学者比较难理解的几个算法之一,这里尽可简单化地讲解,希望能帮到大家. 快速排序基本步骤: 从数列中挑出一个元素,称为"基准"(pivot). 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边).在这个分区结束之后,该基准就处于数列的中间位置.这个称为分区(partition)操作. 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序. 下面这幅图会帮助你理解.选中的pivot用蓝色表示:

排序算法之快速排序(Quick Sort) -- 适用于Leetcode 75 Sort Colors

Quick Sort使用了Divide and Concur的思想: 找一个基准数, 把小于基准数的数都放到基准数之前, 把大于基准数的数都放到基准数之后 Worst case: O(n^2) Average case: O(nlogN) 步骤: 初始的数组 Array a[]: 0 1 2 3 4 5 6 7 8 9 51 73 52 18 91 7 87 73 48 3 基准数: X = a[0] = 51 i 的值: i = 0 j 的值: j = 9 (a.length) Step 1:

PAT_A1101#Quick Sort

Source: PAT A1101 Quick Sort (25 分) Description: There is a classical process named partition in the famous quick sort algorithm. In this process we typically choose one element as the pivot. Then the elements less than the pivot are moved to its lef

C++: quick sort(快排序)

到目前为止, 我们已经学习到了插入排序, 冒泡排序, 选择排序(selection). 这些排序算法都是comparision based sorting algorithms(即涉及到元素大小的比较来决定元素的先后顺序). 而且算法的时间复杂度上均为O(n^2).但是comparision based 的排序算法远非这几个算法. 而且可以通过利用其它的一些手段(例如divide and conquer technique, 分治法)实现对基于比较的排序算法的时间复杂度降低到O(nlogn).

Quick Sort

(referrence: GeeksforGeeks) Like Merge Sort, Quick Sort is also a divide & conquer problem. It picks an element as pivot and partitions the given array around the picked pivot. Different versions of Picking pivot 1. Always pick first element as pivot