算法之排序算法浅谈
来源:互联网 发布:log4j源码讲解 编辑:程序博客网 时间:2024/04/30 08:39
在8大排序算法之间的时间复杂度,辅助空间以及稳定性情况如下表1:
表1
一:快速排序。
快速排序的核心在鱼partition函数部分,如何选择pivot分割点,以及如何围绕分割点进行分割;
法一:如下代码
/*** 快速排序法*/public class QuickSort {//运用分治思想,按照每次的中间值分开两部分后,每部分继续递归去分为两部分排序public void Quick_Sort(int A[],int start,int end){int position = QCCore01(A, start, end);if(position>start){Quick_Sort(A,start,position-1);}if(position<end){Quick_Sort(A,position+1,end);}}//快排核心部分,选取一个分界值,然后把数组分为两部分,运用前后两指针对向移动方法private int QCCore01(int A[],int start,int end){int key = A[start];//这里取的是第一个元素作为分界值while(start<end){ //右指针先左移,直到遇到“小”值 while(A[end]>=key&&start<end){ end--; } //把“小”值交换到左边,把分界值转换过来 if(start<end){ int temp = A[end]; A[end] = key; A[start] = temp; } //左指针右移,直到遇到“大”值 while(A[start]<=key&&start<end){ start++; } //把“大”值交换到右边,把分界值转换过来 if(start<end){ int temp = A[start]; A[start] = key; A[end] = temp; } }return start;//返回中间值的标号}}该方法比较常用,即选择每次排序段数组第一个元素作为pivot元素,然后两遍依次向中间夹逼,每次都是与pivot元素交换;
法二:代码如下
/*** 快速排序法*/public class QuickSort {//运用分治思想,按照每次的中间值分开两部分后,每部分继续递归去分为两部分排序public void Quick_Sort(int A[],int start,int end){int position = QCCore02(A, start, end);if(position>start){Quick_Sort(A,start,position-1);}if(position<end){Quick_Sort(A,position+1,end);}} //快排核心部分,运用双指针同时从前向后,产生大小差值,并根据差值数替换。 private int QCCore02(int A[],int start, int end){ int small = start;//记录“小”值的数目,big遇到“大”值不增加,遇到“小”值才增加 int big = start+1;//代表当前指针去遍历元素 int key = A[start];//取第一个数作为分界值 //双指针去遍历 while(big<=end){ if(A[big]<key){ small++; if(big!=small){ int temp = A[big]; A[big] = A[small]; A[small] = temp; } } big++; } //最后需要交换分界值到指定位置 int temp = A[small]; A[small] = A[start]; A[start] = temp; return small;//返回分界值的位置 }}该方法pivot元素仍然是选择数组段第一个元素作为分割点,但是交换方法上改为比较巧妙的双指针同向运动,一个small指针表示当前最后一个小段元素,big指针表示当前最后一个大段元素,即保证两个指针间的元素都为大段元素,最后只需要把pivot元素放在small指针后面即可(该方法的交换不是鱼pivot元素直接交换);
法三:代码如下
/** * 快速排序 * */public class QuickSort {/** * 主调用方法 * */public void quickSort(int[] array,int n){if(n>2){this.recurSort(array, 0, n-1);}}/** * 递归进行不断划分,首先进行三个元素间的分割点选择,接着进行划分,并递归 * */private void recurSort(int[] array,int start,int end){if(start<end){int pivot = (end-start)/2+start;this.threeSort(array, start, pivot, end);int curPivot = this.partition(array, pivot, start+1, end-1);this.recurSort(array, curPivot+1, end);this.recurSort(array, start, curPivot-1);}}/** * 对数组中三个位置进行排序,针对于快排中的选分割点,选择左中右三个元素中的中间元素作为分割点,防止最坏情况发生; * 如果不采用该选择策略,该方法可以不用; * */private void threeSort(int[] array,int l,int m,int r){if(array[l]>array[m]){this.swap(array, l, m);if(array[r]<=array[l]){this.swap(array, r, l);this.swap(array, m, r);}else if(array[r]<=array[m])this.swap(array, m, r);}else{if(array[r]<=array[l]){this.swap(array, r, l);this.swap(array, m, r);}else if(array[r]<=array[m])this.swap(array, m, r);}}/** * 交换两数组中两个元素位置 * @param i 位置1 * @param j 位置2 * */private void swap(int[] array,int i,int j){int temp = array[i];array[i] = array[j];array[j] = temp;}/** * 一次快排的划分 * @param array 待排序数组 * @param pivot 划分点的序号 * @param start 数组中划分段的起始点序号 * @param end 数组中划分段的结束点序号 * */private int partition(int[] array,int pivot,int start, int end){int pivotIndex = pivot;if(start<end){/*记录结束点的序号*/int toail = end;/*记录划分点的值*/int value = array[pivot];/*把划分点与划分段最后一个数交换,即把划分点的值放到最后*/this.swap(array, pivot, end);end--;/*主循环*/while(start<end){if(array[start]<value)start++;else if(array[end]>=value)end--;else{this.swap(array, start, end);}}/*循环出来后,做扫尾工作,准备还原分割点*//*当start的值大于分割点,则必须交换*/if(array[start]>=value){this.swap(array, start, toail);pivotIndex = start;}/*如果start的值小于分割点的值,则交换start右边一个元素与分割点;如果右边没有元素,则保持不动*/else if(array[start]<value && start+1<toail){this.swap(array, start+1, toail);pivotIndex = start+1;}else{pivotIndex = toail;}}return pivotIndex;}}该方法是通过把pivot元素一开始就放置到数组末端,然后双指针向中间夹逼,同时找到一大一小才互相交换元素,而不是与pivot元素交换;在选择pivot的方法上,当然允许继续选择数组段的第一个元素作为pivot元素,但是这里提供了一个threeSort()函数,该函数是将数组段的最左,中间,最右三个元素排序后返回中间元素的序号,将该元素作为pivot即可防止快排最坏情况的发送。
0 0
- 算法之排序算法浅谈
- 浅谈排序算法(一)之冒泡排序
- 浅谈排序算法(二)之选择排序
- 浅谈排序算法(三)之堆排序
- 浅谈排序算法之归并排序
- 浅谈快速排序算法
- 浅谈算法--排序
- 插入排序算法浅谈
- 排序算法--浅谈
- 浅谈排序算法学习之归并排序merger(一)
- 浅谈排序算法学习之基数排序,又称桶子排序(二)
- 浅谈排序算法学习之希尔排序(三)
- 浅谈排序算法之---冒泡排序
- 算法之排序算法
- 算法之排序算法
- 算法之排序算法
- 算法之排序算法
- 算法之排序算法
- PHP_EOL
- 9.Swift UIImagePickerController选取图片
- Struts2 MySQL数据库访问
- 链特异性转录组测序
- thread类与Runnable接口的区别
- 算法之排序算法浅谈
- javaWEB项目心得之模块开发步骤
- [iOS进阶]SDWebImage 学习小结
- 【Android应用源码分析】Java多线程:线程本地变量ThreadLocal源码分析
- Ubuntu14.04更改默认终端
- Huffman编码
- 洛谷test 2015.10.6 NOIP模拟赛
- javascript原来还可以这样玩
- Struts2中参数传递与OGNL