快速排序是一个对冒泡排序改进的排序。
工作原理:①、设置两个指针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);
算法的稳定性:快速排序在交换过程中,元素的位置会大幅度的交换,当有相同元素时排序结束后位置可能发生变化,是不稳定排序。
算法适用的场合:
快速排序是目前在所有排序算法中最好的算法(除特殊场合),当代排序的序列无序时,快速排序的平均时间最短。