快速排序是一个最坏情况时间复杂度为
我们现在有一数组
那下面我们就来找一个数组
即:
让然后我们对剩下的两个子数组
总的来说,可以分为下面几个步骤:
我们首先采用两种代码实现
/*************************************************
* @Filename: quickSort.cc
* @Author: qeesung
* @Email: qeesung@qq.com
* @DateTime: 2015-05-14 14:48:35
* @Version: 1.0
* @Description: 快速排序的算法实现
**************************************************/
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
void exchange(int array[] , int pos1 , int pos2)
{
if(array == NULL)
return;
int temp = array[pos1];
array[pos1] = array[pos2];
array[pos2] = temp;
}
/**
* 快速排序的递归算法
* @param array 将要排序的数组
* @param leftBorder 排序的左边界
* @param rightBorder 排序的右边界
*/
void quickSortKernel(int array[] , int leftBorder , int rightBorder)
{
if(array == NULL || leftBorder >= rightBorder )
return;
/** 现在对数据进行原址排序 */
int i = leftBorder-1;
int j = leftBorder;
int x = array[rightBorder];
for(; j < rightBorder ; ++j)
{
if(array[j] <= x)
{
exchange(array,++i, j);
}
}
exchange(array ,++i , rightBorder);
/** 递归的排序数组剩下的部分,将合适的数据放在适合的位置上 */
quickSortKernel(array , leftBorder , i-1);
quickSortKernel(array , i+1, rightBorder);
}
/**
* 快速排序接口
* @param array 输入的数组
*/
void quickSort(int array[] , int arraySize)
{
if(array == NULL)
return ;
quickSortKernel(array , 0 , arraySize-1);
}
/**
* 打印数组
* @param array 数组指针
* @param arraySize 数组大小
*/
void printArray(int array[] , int arraySize)
{
if(array == NULL)
return;
for (int i = 0; i < arraySize; ++i)
{
cout<<array[i]<<"\t";
}
cout<<endl;
}
int main(int argc, char const *argv[])
{
int array[10];
int arraySize = sizeof(array)/sizeof(int);
srand((int)(time(NULL)));
for (int i = 0; i < arraySize; ++i)
{
array[i] = rand()%100;
}
cout<<"before sort the array:"<<endl;
printArray(array , arraySize);
quickSort(array , arraySize);
cout<<"after sort the array:"<<endl;
printArray(array ,arraySize);
while(1);
return 0;
}
程序运行结果为:
before sort the array:
24 71 30 26 16 23 56 21 68 30
after sort the array:
16 21 23 24 26 30 30 56 68 71
下面采用第二种方法实现了quickSortKernel()函数
/**
* 采用d递归来排序的数组
* @param array 数组
* @param leftBorder 左边界
* @param rightBorder 右边界
*/
void quickSortKernel(int array[] , int leftBorder , int rightBorder)
{
if(array == NULL || leftBorder >= rightBorder)
return;
int i=leftBorder;
int j = rightBorder-1;
while(1)
{
// i向右边寻找比array[rightBorder]大的元素
while(i < rightBorder && array[i] <= array[rightBorder])
++i;
// j 向左边寻找比array[rightBorder小的元素]
while(j >= i && array[j] >= array[rightBorder])
--j;
if(j+1 != i)
{
exchange(array , i , j);
}
else
{
break;
}
}
exchange(array , i , rightBorder);
quickSortKernel(array , leftBorder , i-1);
quickSortKernel(array , i+1 , rightBorder);
}
运行结果为:
before sort the array:
36 14 24 79 0 71 9 33 77 5
after sort the array:
0 5 9 14 24 33 36 71 77 79
上面两种方法起始很相似,都是采用了递归的方法,只是前一种方法找目标位置
如果快速排序输入的数组时一个按照降序排序的数组,那么快速排序的将达到最差运行时间
那怎么避免快速排序的最差情况呢?我们来分析一下最坏运行时间的发生情况,那就是子数组的极度不平衡。我们知道在每次找到目标位置
为什么上面两种情况会有如此大的区别呢?我们可以将问题划分为两个子问题的情形用二叉树表示出来,如果每次划分数组,其中一个子数组为空,那么每次只能使问题的规模减小1,那么这棵二叉树的深度也将会是
我们推广到一般情况下来看,假设我们得到的两个子数组里面的元素比为
同理可知
通过上面分析可知只要我们保证两个子数组里面任何一个都不为空,那么运行时间都是
/**
* 采用d递归来排序的数组
* @param array 数组
* @param leftBorder 左边界
* @param rightBorder 右边界
*/
void quickSortKernel(int array[] , int leftBorder , int rightBorder)
{
if(array == NULL || leftBorder >= rightBorder)
return;
// 为了防止是一个纯升序或者是降序的数组,
// 现在选取数组中前中后三个元素,得到第二大的那个
int center = (leftBorder + rightBorder)/2;
if(array[leftBorder] > array[center] && array[rightBorder] < array[center])
exchange(array , center , rightBorder);
else if(array[leftBorder] > array[center] && array[rightBorder] > array[leftBorder])
exchange(array , leftBorder , rightBorder);
int i=leftBorder;
int j = rightBorder-1;
while(1)
{
// i向右边寻找比array[rightBorder]大的元素
while(i < rightBorder && array[i] <= array[rightBorder])
++i;
// j 向左边寻找比array[rightBorder小的元素]
while(j >= i && array[j] >= array[rightBorder])
--j;
if(j+1 != i)
{
exchange(array , i , j);
}
else
{
break;
}
}
exchange(array , i , rightBorder);
quickSortKernel(array , leftBorder , i-1);
quickSortKernel(array , i+1 , rightBorder);
}
输入一个数组,首先取出数组头部,数组尾部,数组中部的三个元素,得到这三个元素的第二大的那个元素作为主元,你也可以不这么选,你选出前面三个元素其实也可以。我们只要保证没有一个子数组为空即可!
运行结果为:
before sort the array:
92 17 47 13 89 13 58 25 42 10
after sort the array:
10 13 13 17 25 42 47 58 89 92
原文地址:http://blog.csdn.net/ii1245712564/article/details/45749061