*排序算法目录 **
冒泡排序(Bubble Sort)
选择排序(Selection Sort)
插入排序(Insertion Sort)
希尔排序(Shell Sort)
归并排序(Merge Sort)
快速排序(Quick Sort)
堆排序(Heap Sort)
鸽巢排序(Pigeonhole Sort)
快速排序(Quick Sort)
快排同样采用分治法,在逻辑上也有点类似于归并排序;不同于归并排序的是,快排不需要额外空间,且每次都会大量的降低比较次数,从而提高效率。
代码逻辑:
先找一个基准值(一般选取第一个元素),将数组分割为两部分,小的在前,大的在后,继续此操作至排序完毕。
实现逻辑:
(1)以第一个元素做分割,小于它的放在前面,大于它的放在后面;
(2)对于分割的数组做重复处理,直至分割为单个元素;
注:每次先从后往前找第一个小于分隔元素的值将其赋给分隔元素的下标,t记住的是分割元素,i,j分别记住交换后元素下标,然后作交换时直接覆盖;
时间复杂度:
平均时间复杂度:O(NlogN)
最佳时间复杂度:O(NlogN)
最差时间复杂度:O(N²)
稳定性:不稳定
图示:
实现代码:
#include <stdio.h>
#include <malloc.h>
void Show(int * p, int len)
{
for (int i = 0; i < len; ++i)
{
printf("%d,", p[i]);
}
puts("\b;");
}
void QSort(int*p, int first, int last) //快速排序辅助函数
{
if (first >= last) //当首元素下标大于末元素下标或二者重合,则return
return;
int t = p[first]; //t记住首元素,用来分割数组并定位p[first]
int i = first; //i记住首元素下标
int j = last; //j记住末元素下标
while (i < j) //当首元素下标小于末元素下标时进行此流程
{
while (i<j && p[j] > t) //当i<j且p[j]大于t时
j--; //j--,找未越界并且小于t(分割元素)的元素下标
if (i < j) //当j未越界
p[i++] = p[j]; //将p[j]赋值给p[i],i后移一位
while (i<j && p[i] <= t) //当i<j且p[j]小于等于t时
i++; //i++,找未越界并且大于等于t(分割元素)的元素下标
if (i < j) //当i未越界
p[j--] = p[i]; //将p[i]赋值给p[j],j前移一位
}
p[i] = t; //当i,j相遇时,将分隔元素t插入当前位置
QSort(p, first, i - 1); //对分割的数组继续重复此流程直至分割为单个元素
QSort(p, j + 1, last);
}
void QuickSort(int* p, int len) //快速排序
{
QSort(p, 0, len - 1);
}
int main()
{
int arr[] = { 2,13,7,6,15,9,10,12,3,16,8,11,14,5,1 };
int len = (int) sizeof(arr) / sizeof(*arr);
QuickSort(arr, len);
Show(arr, len);
return 0;
}
**总结:**快速排序是这几种排序方法中效率最高的排序算法,而且其适用于大多数场景,对原数列也没有过多要求;因此在毫无规律的数列排序中,其效率高于其他算法,且快排对于大量数据的处理也有很高的效率。
快排的代码逻辑有点类似于归并排序,归并排序是在分割后将元素和性的过程中有效排序,而快排是在分割时做排序处理,因而归并排序是稳定的,而快速排序不稳定。