快速排序
快速排序使用分治法策略,它的基本思想是
选择一个基准数,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据要小,然后,再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列
快速排序流程
1.从数列中选一个基准值;
2.将所有比基准值小的摆放在基准前面,所有比基准值大的摆在基准的后面(相同
的数可以任一边),在这个分区退出之后,该基准就处于数列的中间位置;
3.递归的把“基准值前面的子数列”和“基准值后面的子数列”进行排序。
思维导图
示例
代码
//快速排序
//arr--->待排序的数组
//left--->数组的左边界(例如从起始位置开始排序,那left=0)
//right--->数组的右边界(例如,排序截止到数组末尾,那right=数组的总个数-1)
//x--->是每次排序找的基准值
#include<stdio.h>
#include<stdlib.h>
void quick_sort(int arr[], int left,int right)
{
int i = left;
int j = right;
int x = arr[i];
//i>=j时,就说明已经把x排到正确的位置了
if (i < j)
{
while (i < j)
{
while (i < j && arr[j] > x)//从右往左找第一个小于x的数
j--;
if (i < j)
/*赋值之后,把i往后移动一个位置,因为i前面的数肯定
比x小,故在下次查找大于x得值时,不用参与比较*/
arr[i++] = arr[j];
while (i < j&& arr[i] < x)//从左往右找第一个大于x的数
i++;
if (i < j)
arr[j--] = arr[i];//赋值之后,把j往前移动一个位置,因为j后面的数肯定比x大
}
arr[i] = x;//此时i和j指向的是同一个位置,故也可以写arr[j]=x
//递归调用的对基准值两边的序列进行快速排序
quick_sort(arr, left, i - 1);//i==j时,就不用进入此函数了,故必须i<j
quick_sort(arr, i + 1, right);//i==j时,就不用进入此函数了
}
}
void Print(int arr[], int sz)
{
for (int i = 0; i < sz; i++)
printf("%d ", arr[i]);
printf("\n");
}
int main()
{
int arr[] = { 1, 5, 3, 29, 78, 12, 11, 59, 7, 8, 2, 5,
4, 9, 12,23, 10, 15, 11, 2, 3, 6, 35, 20,
19,67, 59, 99 };
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
Print(arr, sz);//打印数组
quick_sort(arr, left,right);
Print(arr, sz);
system("pause");
return 0;
}
运行结果
时间复杂度
快速排序的时间复杂度在最坏情况下是O(n^2)