分支算法--快速排序

来源:互联网 发布:记忆碎片软件下载 编辑:程序博客网 时间:2024/04/29 20:48

一.算法介绍

快速排序(Quicksort 有时称为partition-exchange排序)是一种有效的排序算法,作为系统的方法将一个数组的元素。当实现,它可以两到三倍的速度比其主要竞争对手,归并排序和堆排序。快速排序是一种比较,这意味着它可以排序项小于关系的任何类型的定义(在形式上,全序)。在高效的实现,它不是一种稳定的,这意味着平等的相对顺序排序项不保存。快速排序数组可以就地操作,需要少量额外的内存来执行排序。https://en.wikipedia.org/wiki/Quicksort#Analysis_of_randomized_quicksort

二.复杂度分析

平均而言,该算法需要O(n log n)比较n项进行排序。在最坏的情况下,它使O(n2)比较,尽管这种行为是罕见的。

三.算法思想及步骤

1)       分解(Divide):    数组A[p..r]被划分成为两个(可能为空)子数组A[p..q-1]A[q+1..r],使得A[p..q-1]中的每个元素都小于等于   A(q),而且小于等  于A[q+1..r]中的元素,下标q也在划分的过程中进行计算.

2)      解决(Conquer):通过递归调用快速排序,对子数组A[p..q-1],A[q+1..r]排序.

3)      合并(Conbine):因为两个子数组是就地排序的,将他们的合并不需要操作:整个数组A[p..r]已排序.

伪码如下:

//QUICKSORT(A,p,r)if p < rthen q <-- PARTITION(A,p,r)QUICKSORT(A,p,q-1)QUICKSORT(A,q+1,r)

QUICKSORT函数中三个参数的意义: A待排序数组  p 排序开始标志位  r 待排序数组A的长度.

如果想要给一个完整的数组A排序,那么就需要执行QUICKSORT(A,1,length[A]).

从上面的排序过程可以看出3,4都是递归调用解决子问题,而就地排序的过程在PARTITION中进行。所以重点理解PARTITION。

//PARTITION(A,p,r) x <-- A[r] i  <-- p-1 for j <-- p to r-1 <span style="white-space:pre"></span>if A[j] <= x <span style="white-space:pre"></span>then  i <-- i+1<span style="white-space:pre"></span>exchange A[i] <--> A[j] exchange A[i+1] <--> A[r] return i+1

示例模拟

不怎么好用的在线演示请点击这里Quick-Sort

Wiki图库给出如下模拟

四.C代码

#include<stdio.h>void quicksort(int a[],int l,int r){if(l<r){int i,j,t;i=l,j=r,t=a[l];while(i<j){while(i<j&&a[j]>=t) // 从右向左找第一个小于t的数 j--;if(i<j)a[i++]=a[j];while(i<j&&a[i]<t) // 从左向右找第一个大于t的数i++;if(i<j)a[j--]=a[i];}a[i]=t;quicksort(a,l,i-1);quicksort(a,i+1,r);}}int main(){int a[20],n;while(scanf("%d",&n)!=EOF&&n){for(i=0;i<n;i++)scanf("%d",&a[i]);quicksort(a,0,n-1);for(i=0;i<n;i++)printf("%d ",a[i]);puts("");}return 0;}



0 0