您的位置:首页 > 其它

《算法导论》读书笔记--快速排序

2016-01-10 14:08 253 查看
快速排序是最坏情况时间复杂度为O(n²),最优时间复杂度为O(nlgn),平均时间复杂度为O(nlgn)。

最坏情况出现在每一层划分子问题时,分别包含了n-1个元素和0个元素,此时的时间复杂度为O(n²),与插入排序相同;在数组已经有序时其时间复杂度依旧为O(n²),此时插入排序的时间复杂度为O(n)。

快速排序使用了分治思想,将数组A[p..r]划分为两个子数组A[p..q-1]和A[q+1..r],使A[p..q-1]中的元素都小于A[q],A[q+1..r]中的元素都大于A[q],不断进行递归这个过程,直到数组中只存在一个元素,此时,数组已经有序。

QUICKSORT(A,p,r)
if p < r //当数组中只剩一个元素时,退出递归,数组已经有序
q = PARTITION(A,p,r)
QUICKSORT(A,p,q-1) //对小于等于A[q]的元素进行递归
QUICKSORT(A,q+1,r) //对大于A[q]的元素进行递归


划分数组:

PARTITION(A,p,r)
x = A[r] //将A[r]选取为“主元”
i = p - 1 //因为可能不存在小于等于A[r]的元素,所以i的值由p-1开始
for j = p to r-1
if A[j] <= x
i = i + 1 //小于等于x的元素增加一个
exchange A[i] with A[j] //i+1后,i指向了一个大于x的元素,此时,j指向的是一个小于等于x的元素,交换这两个元素的位置,使其符合规则
exchange A[i+1] with A[r] //r前所有元素比较完后,将A[r]置于正确位置:两个子数组的交界处
return i + 1 //返回"主元"的位置


在整个for循环过程中,数组被划分为了四个区域:

1.小于等于A[r],元素位于[p,i]

2.大于等于A[r],元素位于(i,j)

3.未划分区域 [j,r)

4.主元 [r,r]

Demo:

#include <iostream>
#include <stdio.h>
using namespace std;

void swap(int *a,int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
}

int partition(int *A,int p,int r)
{
int i = p - 1;
int x = A[r];
for(int j = p;j < r;j++)
{
if(A[j] <= x)
{
i++;
swap(A[j],A[i]);
}
}
swap(A[r],A[i+1]);
return (i + 1);
}

void quicksort(int *A,int p,int r)
{
if( p < r )
{
int q = partition(A,p,r);
quicksort(A,p,q-1);
quicksort(A,q+1,r);
}
}

int main()
{
int A[10];
for(int i = 0;i < 10;i++)
cin>>A[i];
quicksort(A,0,9);
for(int i = 0;i < 10;i++)
cout << A[i] <<" ";
getchar();
system("pause");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: