快速算法是一种分治的递归算法。
快速算法的思路:首先从待排序记录中选一个分割记录,接着调整所有待排序记录,将分割记录放置在一个位置,使得分割记录左边的关键字不大于分割记录的关键字,使得分割记录右边的关键之不小于分割记录的关键字,最后把分割记录左边的那些记录和右边的那些记录分别看成两个独立表,再对两个表分别排序(递归调用快速排序法)。
array_num[MAX_NUM]={34,6,24,4,81,31,69,14,38,10};//需要排序的原始数组
R1 R2 R3 R4 R5 R6 R7 R8 R9 R10 left right
(34 6 24 4 81 31 69 14 38 10) 0 9
(14 6 24 4 10 ) 31 34 69 38 81) 0 5
(4 6 10) 14 24 31 34 69 38 81 0 2
4 (6 10) 14 24 31 34 69 38 81 1 2
4 6 10 14 ( 24 31) 34 69 38 81 4 5
4 6 10 14 24 31 34 (69 38 81) 7 9
4 6 10 14 24 31 34 38 69 81 9 9
核心算法:
void quick_sort_two(int r[],unsigned int left,unsigned int right)
{
unsigned int i=0,j=0;
unsigned int pivot=0;
unsigned int temp=0;
static unsigned int count_two=0;
if(left<right)
{
i=left;
j=right+1;
pivot=r[left];
//每一轮while循环就可以实现数列按照这个基准左边小,右边大
do
{
//从左到右以此找比基准大的值
do i++;while((pivot>r[i]));
//从右到左以此找比基准小的值
do j--;while((pivot<r[j]));
//将左边找到比基准大的值和右边找到比基准小的值位置交换
if(i<j)
{
temp=r[j];
r[j]=r[i];
r[i]=temp;
}
}while(i<j);
//将小于基准值的最大值与基准值位置交换
temp=r[j];
r[j]=r[left];
r[left]=temp;
if(j>left)//如果左边没有比完就需要继续
quick_sort_two(r,left,j-1);
if(j<right)//如果右边没有比完就需要继续
quick_sort_two(r,j+1,right);
}
}
快速排序的平均计算时间,递归深度以及需要的栈空间,随后更新讨论补充。
完整的代码放在下面,对于快速排序有两种方法,供大家参考,我命名quick_sort_one和quick_sort_two:
#include<stdio.h>
#include<string.h>
/*
本程序介绍第二(NUM_TWO): 快速排序(QuickSort)
*/
#define MAX_NUM 10 //需要排列总数
#define TRUE 1 //有数据交换为真
#define FALSE 0 //没有数据交换是假
void quick_sort_one(int r[],unsigned int left,unsigned int right);
void quick_sort_two(int r[],unsigned int left,unsigned int right);
void printf_string(int *b,unsigned int len);//打印数据
//主函数
int main(void)
{
unsigned int i=0;
static int array_num[MAX_NUM]={34,6,24,4,81,31,69,14,38,10};//需要排序的原始数组
//quick_sort_one(array_num ,0,MAX_NUM-1);//快速排序
quick_sort_two(array_num ,0,MAX_NUM-1);//快速排序
while(1);
return 0;
}
//核心算法
void quick_sort_one(int r[],unsigned int left,unsigned int right)
{
unsigned int i=0,j=0;
unsigned int pivot=0;
static unsigned int count=0;
i=left;
j=right;
pivot=r[left];
if(i<j)
{
//每一轮while循环就可以实现数列按照这个基准左边小,右边大
while(i<j)
{
//从右到左以此找比基准小的值
while((i<j)&&(pivot<=r[j]))j--;
if(i<j)
{
r[i]=r[j];
// i++;//此刻r[i]已经满足条件因此不用再比较
}
//从左到右以此找比基准小的值
while((i<j)&&(pivot>=r[i]))i++;
if(i<j)
{
r[j]=r[i];
// j--;//此刻r[j]已经满足条件因此不用再比较
}
}
r[i]=pivot;
count++;
printf("第%3d次分割,基准为%3d,排列顺序为:",count,pivot);
printf_string(r,MAX_NUM);
if(i>left)//如果左边没有比完就需要继续
quick_sort_one(r,left,i-1);
if(i<right)//如果右边没有比完就需要继续
quick_sort_one(r,i+1,right);
}
}
void quick_sort_two(int r[],unsigned int left,unsigned int right)
{
unsigned int i=0,j=0;
unsigned int pivot=0;
unsigned int temp=0;
static unsigned int count_two=0;
if(left<right)
{
i=left;
j=right+1;
pivot=r[left];
//每一轮while循环就可以实现数列按照这个基准左边小,右边大
do
{
//从左到右以此找比基准小的值
do i++;while((pivot>r[i]));
//从右到左以此找比基准小的值
do j--;while((pivot<r[j]));
if(i<j)
{
temp=r[j];
r[j]=r[i];
r[i]=temp;
}
}while(i<j);
temp=r[j];
r[j]=r[left];
r[left]=temp;
count_two++;
printf("left=%3d,right=%3d,",left,right);
printf("第%3d次分割,基准为%3d,排列顺序为:",count_two,pivot);
printf_string(r,MAX_NUM);
if(j>left)//如果左边没有比完就需要继续
quick_sort_two(r,left,j-1);
if(j<right)//如果右边没有比完就需要继续
quick_sort_two(r,j+1,right);
}
}
//打印数据
void printf_string(int *b,unsigned int len) //打印数据
{
unsigned int i=0;
for(i=0;i<len;i++)
{
printf("%3d",b[i]);
}
printf("\n");
}