简介
快速排序是利用递归原理来实现的常用排序算法,本篇文章介绍使用快速排序对数组进行排序。
数组为空或者只有一个元素是不需要进行排序的,所以快速排序递归的基线条件为数组长度少于2。
基本原理
首先,从数组中选择一个元素,这个元素被称为基准值(pivot)。然后,找出比基准值小的元素以及比基准值大的元素,此过程称为分区(partioning)。进行分区之后,得到的两个子数组是无序的。
比如对数组
5 | 2 | 4 | 1 | 3 |
选择最后一个元素3为基准值进行分区得到
2 | 1 | 3 | 5 | 4 |
现在我们得到:
- 一个由所有小于基准值组成的子数组
- 基准值
- 一个由所有大于基准值组成的子数组。
对两个子数组递归进行上述操作。
C语言的快速排序示例
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
void myswap(void *a, void *b, size_t width)
{
char tmp;
int i;
for (i = 0; i < width; i++){
tmp = *((char*)a + i);
*((char*)a + i) = *((char*)b + i);
*((char*)b + i) = tmp;
}
}
int partitioning(int *arr, int l, int r)
{
//选择数组最后一个元素为基准值
int pivot = arr[r];
//小于基准值的最后索引
int last_less_idx = l - 1;
for (int i = l; i < r; i++){
if (arr[i] < pivot){
last_less_idx++;
myswap(&arr[i], &arr[last_less_idx], sizeof(int));
}
}
//把基准值和第一个大于基准值的元素交换
myswap(&arr[last_less_idx + 1], &arr[r], sizeof(int));
//返回分区后基准值的索引
return last_less_idx + 1;
}
void myqsort(int *arr, int l, int r)
{
int partition_idx;
if (l >= r)
return;
partition_idx = partitioning(arr, l, r);
myqsort(arr, l, partition_idx - 1);
myqsort(arr, partition_idx + 1, r);
}
void show_arr(int *arr, int l, int r)
{
for (int i = l; i <= r; i++){
printf("%d ", arr[i]);
}
}
int main(int argc, char* argv[])
{
int arr[10];
int i;
srand(time(NULL));
for (i = 0; i < 10; i++){
arr[i] = rand() % 100;
}
printf("show array before qsort\n");
show_arr(arr, 0, 9);
myqsort(arr, 0, 9);
printf("\nshow array after qsort\n");
show_arr(arr, 0, 9);
return 0;
}