排序(二)快速排序
快排是冒泡排序的改进版,虽然最坏的情况下时间复杂度依然是O(n2),但平均时间复杂度变成了O(n*log2n)。
算法:(介绍升序,其它类似,算法不唯一)
以数组int arr[10] = {20,12,50,34,16,66,27,5,10,33}为例
定义int i = 0,int j = 9
1.选基准,将第0个数存起来
即 20,12,50,34,16,66,27,5,10,33
基准20
比较时将比基准小的数放左边,比基准大的数放右边
2.先逆序比较:一直比较,直到遇到比基准小的数,
比较一次(j - -)如果(i >= j)跳出循环
第一次逆序比较结果
20<33,不变,再比较20>10,将10放在基准的位置,跳出循环,执行第3步
10,12,50,34,16,66,27,5,10,33
第二次逆序比较结果
20>5,将5放在刚才50的位置
10,12,5,34,16,66,27,5,50,33
第三次逆序比较结果
20<27,不变,20<66,不变,20>16,将16放在刚才34的位置
10,12,5,16,16,66,27,34,50,33
3.正序比较:一直比较,直到遇到比基准大的数
比较一次 (i ++)如果(i >= j)跳出循环
第一次正序比较结果
20>12,不变,20<50,将50放到刚才10的位置,跳出循环,执行第2步
10,12,50,34,16,66,27,5,50,33
第二次正序比较结果
20<34,将34放在刚才5的位置
10,12,5,34,16,66,27,34,50,33
第三次正序比较结果
i 与j相等为4,退出
10,12,5,16,16,66,27,34,50,33
4.如果(i >= j)跳出循环,否则回到第2步
5.跳出循环后(i ==j),此时将基准值赋给a[i];
即10,12,5,16,20,66,27,34,50,33
6.将基准左边和右边的数分开执行第1步(递归)
上代码:代码不唯一
/*************************************************************************
#File Name: qksort.c
#User :cw
#QQ : 948238688
#Email:948238688@qq.com
#Created Time: 2018年10月31日 17时53分30秒 CST
************************************************************************/
#include <stdio.h>
int qksort(int *dest, int low, int high)
{
if(low >= high) //递归退出条件
return 0;
int *arr = dest;
int i = low, j = high;
//取第0个数为基准,并达到保存基准,以防覆盖
int x = arr[i];
while(i<j)
{
//从后往前比较,如果比基准大,继续比较
while(i<j && x<=arr[j])
j–;
/*退出循环后,将值赋给a[i];
不用if(i<j)判断可以节约系统资源
结果是一样的,因为即使退出后i = j,
将a[j]赋给a[i];不影响结果,而加if(i<j)
会多n次判断 */
arr[i] = arr[j];
//以下同理
while(i<j && x>=arr[i])
i++;
//a[j]的值已转a[i],或者i = j,不影响
arr[j] = arr[i];
}
//退出后a[i]存放的有用值已转移,直接放入基准值
arr[i] = x;
/*基准左边重新排序 */
qksort(arr, low, i-1);
/*基准右边重新排序 */
qksort(arr, i+1,high);
return 0;
}
int main(int argc, char *argv[])
{
int i;
int arr[10] = {20,12,50,34,16,66,27,5,10,33};
qksort(arr,0,9);
for(i = 0; i<10; i++)
{
printf("%d “, arr[i]);
}
printf(”\n");
return 0;
}