排序算法 之 快速排序
快速排序是基于分治思想的一种排序算法,就像该方法的名字一样,速度比较快,所以叫做快速排序;它的平均时间复杂度为O(N*logN),最坏时间复杂度为O(n²)。快速排序也有很多优化的版本,比如在排序时基数的选择等等…下面就说一下一般的快速排序的实现。
基本思想:
快速排序的基本思想就是,先从待排序的序列中任选一个元素作为基数,然后将序列中的其他小于基数的元素放在基数的左边,大于或等于基数的元素放在基数的右边,第一次的时候虽然序列中的左半部分中的元素都小于基数,序列中右半部分中的元素都大于或等于基数,但这两部分内部元素并不一定是有序的,不要紧,只要我们把左右两半部分序列分别继续执行第一步,这样不断的把序列分解然后排序,直到分到最后所分解的序列中元素的数量都为1,则排序完成序列有序。
下面看图:这是一个待排序的序列
5 | 2 | 6 | 1 | 7 | 8 | 4 | 9 | 3 |
第一步,选择基数,一般选择序列的首个元素为基数,这里选择首个元素5为基数,并记录在临时变量中,记录此时序列的起始位置下标i=0,结束位置下标j=8;
第二步,从位置j开始向左找,每移动一个位置j--,当找出一个小于基数的元素时把该元素放入刚才选择基数的位置即(i=0),同时使i++;如下图:
3 | 2 | 6 | 1 | 7 | 8 | 4 | 9 | 3 |
第三步,从位置i开始向右找,每移动一个位置i++,当找出一个大于或等于基数的元素时把该元素放入位置j,同时j--;如下图:
3 | 2 | 6 | 1 | 7 | 8 | 4 | 9 | 6 |
第四步,重复执行第二、第三步直至i==j时结束,然后把基数放入位置i;最后如下图:
3 | 2 | 4 | 1 | 5 | 8 | 7 | 9 | 6 |
第五步,将基数左右两边的序列重复执行第一、二、三、四、五步直至最后分解的所有序列中元素数量都为1则排序结束序列有序。
有了上面的分析过程下面看代码实现:
/// <summary> /// 快速排序 /// </summary> /// <param name="intArray"></param> /// <param name="left"></param> /// <param name="right"></param> public static void QuickSort(int[] intArray, int left, int right) { if (left < right) { int i = left, j = right, x = intArray[left]; while (i < j) { //从右向左找小于x的数来填intArray[i] while (i < j && intArray[j] >= x) { j--; } if (i < j) { intArray[i] = intArray[j]; i++; } //从左向右找大于或等于x的数来填intArray[j] while (i < j && intArray[i] < x) { i++; } if (i < j) { intArray[j] = intArray[i]; j--; } }//退出循环时 i==j intArray[i] = x; QuickSort(intArray, left, i - 1); QuickSort(intArray, i + 1, right); } }
当调用时left传入序列开始的下标即0,right传入序列结束的下标即(长度-1);
以上就是快速排序的实现。