快速排序算法
难点:递归的思想、中间值的作用
#include <stdio.h>
void quicksort(int num[], int low, int high);
int main(){
int num[10] = {5,2,6,0,3,9,1,7,4,8};//待排序数组
quicksort(num,0,9);
for(int i = 0; i<10 ;i++){
printf("%d ",num[i]);
}
}
void quicksort(int num[], int low, int high){
/*对数组num进行快速排序,low为需要排序区段的最左下标,
high为需要排序区段的最右下标,从小到大排序,O(nlog2^n),不稳定*/
/*核心思想,选中最左num[low]的数值为中间值key
,将小于key的值放在数组左边,大于key的值放在数组右边
,low存入i,high存入j,i和j是变化的,low和high不变
,j循环变小,从右向左找小于key的值,找到后将值存入num[i]
,第一次循环时num[i]正是中间值,因为中间值已经保存在了key中
,所以可以存入num[i],num[j]的值变得无意义
,i循环变大,从左向右找大于key的值,找到后将值存入num[j]
,因为num[j]的值已经到了左边,所以num[i]的值可以存入num[j]
,num[i]的值变得无意义
,全部循环过后,num[i]左边都小于key,右边都大于key
,此时num[i]的值无意义,存入中间值key
,然后递归左右
*/
if(low >= high){//不需要排序,退出
return;
}
int i = low;//i可变,从左往右增大
int j = high;//j可变,从右往左减小
int key = num[low];//将最左元素值选为中间值
while(i < j){//i还没遇见j就继续
while(i < j && num[j] >= key){//元素值不小于中间值key,继续向左移动
j--;
}
num[i] = num[j];//此时num[j]<key,将其值移到左边num[i],此时num[j]值无意义
while(i<j && num[i] <= key){//元素值不大于中间值key,继续向右移动
i++;
}
num[j] = num[i];//此时num[i]>key,将其值移到右边num[j],此时num[i]值无意义
}
num[i] = key;//此时num[i]无意义,存入中间值key
quicksort(num,low,i-1);//递归中间值的左半边
quicksort(num,i+1,high);//递归中间值的右右边
}