快速排序算法概述
- 快速排序是采用一种分治的策略;
- 对输入的无序序列选择一个基准数,然后将比基准数小的放在左边(序列A),比基准数大的放在右边(序列B)(假设现在排序要求升序排列);
- 然后对序列A和序列B分别再做为第二步的输入序列,重复第二步;
- 递归操作上面两步,直到输入序列只剩下一个元素返回,这样整个原始序列就已经变为有序序列;
- 快速排序的平均时间算法复杂度为O(nlogn),最差的情况下时间复杂度为O(n^2)(当每次选择的基准数都是当前序列最大或者最小的数时);
C算法实现
volatile static unsigned count = 0;
static void quickSort(int *baseAddr, unsigned startIDX, unsigned endIDX)
{
int tmp = 0;
int benchData = baseAddr[startIDX];
if(!baseAddr)
{
printf("The pointer can not be NULL!\n");
return;
}
//判断输入序列是否只有一个元素,该条件为递归的结束条件
if(startIDX >= endIDX)
{
return;
}
//每次选择输入序列的第一个元素为基准数;所以从第二个数开始与第一个数比较;
int i = startIDX+1;
int j = endIDX;
while(i<j)
{
count++;//复杂度计数
//如果元素i大于基准数,则将该元素跟序列末尾元素j交换位置,j--;
//并且因为当前i已经发生变化,所以不用i++,下一次循环再比较i跟j的值;
//如果元素i小于等于基准数,则i++,继续下一轮循环;
//当i==j时,退出循环;
if(baseAddr[i] > benchData)
{
tmp = baseAddr[i];
baseAddr[i] = baseAddr[j];
baseAddr[j] = tmp;
j--;
}
else
i++;
}
//因为在最后一次退出循环前有i++操作,i可能已经自增为应该放在基准数右边元素的序号;
if(baseAddr[i] >= benchData)
i--;
//交换i元素和序列第一个元素(基准数);因为基准数肯定是>=i元素的;
baseAddr[startIDX] = baseAddr[i];
baseAddr[i] = benchData;
//对序列的左半部分继续做排序;
quickSort(baseAddr , startIDX, i);
//对序列的右半部分继续做排序;
quickSort(baseAddr , j, endIDX);
return;
}
测试函数如下:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#define ARRAYLEN 1000
#define true 1
#define false 0
typedef unsigned short bool;
//序列是否为升序排列
static bool isAscendingOrder(int *baseAddr, unsigned dataLength)
{
unsigned i = 0;
do
{
if(baseAddr[i]>baseAddr[i+1])
{
//printf("The arrray is not ascending order!\n");
return false;
}
i++;
}while(i<(dataLength-1));
//printf("The arrray is ascending order!\n");
return true;
}
//序列是否为降序排列
static bool isDescendingOrder(int *baseAddr, unsigned dataLength)
{
unsigned i = 0;
do
{
if(baseAddr[i]<baseAddr[i+1])
{
// printf("The arrray is not descending order!\n");
return false;
}
i++;
}while(i<(dataLength-1));
//printf("The arrray is descending order!\n");
return true;
}
int ArrayData[ARRAYLEN] = {};
int main(int argc, char *argv[])
{
//打开linux下的随机数产生设备;
int randFD = open("/dev/urandom", O_RDONLY);
if(randFD <= 0)
{
printf("open the urandom device failed!\n");
return -1;
}
unsigned i = 0;
for(;i<ARRAYLEN;i++)
{
read(randFD, ArrayData+i, sizeof(int));
printf("%d ", ArrayData[i]);
if((i+1) %10 == 0)
printf("\n");
}
close(randFD);
//对产生的随机序列做快速排序;
quickSort(ArrayData, 0, ARRAYLEN-1);
//检查序列是否已经有序;
if(isAscendingOrder(ArrayData, ARRAYLEN))
{
printf("The array is ascending order!\n");
}
else if(isDescendingOrder(ArrayData, ARRAYLEN))
{
printf("The array is descending order!\n");
}
else
{
printf("The array is unordered!\n");
}
printf("The operation count is:%u\n", count);
return 0;
}
然后编译执行:
gcc quickSort.c -o quickSort -Wall
./quickSort