快速排序是一个对冒泡排序改进的排序。
工作原理:①、设置两个指针a和b分别指向序列的开始和最后
②、设置一个参照物(一般是第一个数),由指针b指向的数与参照数进行比较,如果指针指向的数比参照数大,指针左移。如果如果指针指向的数比参照数小,交换他们两个的位置并由指针a操作。
③、由指针a指向的数与参照数进行比较,如果指针指向的数比参照数小,指针右移。如果如果指针指向的数比参照数大,交换他们两个的位置并由指针b操作。
④、在保证指针a<b的同时,重复②、③操作。
看代码:
class Program
{
static void Main(string[] args)
{
int[] arr = { 12, 3, 456, 21, 7, 32, 43 };
int a = 0, b = arr.Length - 1;
QuickSort(arr,a,b);
for (int i = 0; i < arr.Length; i++)
{
Console.Write(arr[i] + " ");
}
}
public static void QuickSort(int[] arr,int a,int b)
{
//如果开始的索引已经大于结束的索引,说明已经排序完成
if (a >= b)
{
return;
}
int i = a, j = b;
int sum = arr[i];//将序列中的第一个数设置为参照数
//保证右侧索引大于左侧索引,如果不大于时就证明整个序列已经遍历完了
while (i < j)
{
//如果参照数比在它右侧的数小,并且左侧索引小于右侧索引,那右侧索引向左推进
while (i < j && sum <= arr[j])
{
j--;
}
arr[i] = arr[j]; //当右侧的数比参照数小得时候,将右侧的数赋值给左侧的数(左侧的数没有消失只是被记录下来了)
//如果参照数比在它左侧的数大,并且左侧索引小于右侧索引,那左侧索引向右推进
while (i < j && sum >= arr[i])
{
i++;
}
arr[j] = arr[i];
}
arr[i] = sum; //该序列已经遍历完,将参照数归位(就是放到中间位置)
//由递归的思想,遍历参照数的左右两侧
QuickSort(arr, a, i - 1);
QuickSort(arr, i + 1, b);
}
}
运行结果为:
时间复杂度分析:
最好情况下是每一次取到的元素都刚好平分整个数组,时间复杂度为O(nlogn);
最坏情况下是数组已经基本有序,每一次取到的都是最大/最小元素,这时就成了冒泡排序了,时间复杂度为O(n^2);
平均时间复杂度为O(nlogn);
算法的稳定性:快速排序在交换过程中,元素的位置会大幅度的交换,当有相同元素时排序结束后位置可能发生变化,是不稳定排序。
算法适用的场合:
快速排序是目前在所有排序算法中最好的算法(除特殊场合),当代排序的序列无序时,快速排序的平均时间最短。