基于交换的排序有以下两种
一、冒泡排序(Bubble Sort)
基本思想:在要排序的一组数中,对当前还未排好的全部数,自上而下相邻的两个依次进行比较和调整,让较大的数往下沉,较小的往上冒。即每当两个相邻的数比较后,发现它们的排序与排序要求相反时,就将它们交换。
代码如下:
<pre name="code" class="java">//正常的冒泡排序 public void bubbleSort(int[] array){ for(int i=0; i<array.length-1; i++){ for(int j=0; j<array.length-1-i;j++){ if(array[j]>array[j+1]){ swap(array,j,j+1); } } } }
交换函数代码:
public static void swap(int[] array,int a,int b){ int temp = array[a]; array[a] = array[b]; array[b] = temp; }
冒泡排序也是经过了两次循环的过程,所以冒泡排序的时间复杂度为O(n^2)。
对冒泡排序算法的改进:
1).对冒泡排序常见的改进方法是加入一个标志性变量exchange,用于标识某一趟排序过程中是否有数据交换,如果进行某一趟排序并没有进行数据交换,则说明数据已经按要求排好了,可立即结束排序,避免不必要的比较过程。
代码如下:
/** * 改进方式一: * 设置一个标记,如果这一趟发生了交换,则该标记设置为true, * 如果这一趟没有发生交换,则将标记设置为false,很显然,如果没有发生交换, * 则说明已经有有序。 */ public void bubbleSort1(int[] array){ boolean flag = true; for(int i=0; i<array.length-1; i++){ //每次先重置为false flag = false; for(int j=0; j<array.length-1-i; j++){ if(array[j] > array[j+1]){ swap(array, j, j+1); flag = true; } } if(flag == false){ break; } } }
2).设置一标志性变量pos,用于记录每趟排序中最后一次进行交换的位置,由于pos位置之后的记录均已交换到位,故在进行下一趟排序的时候只扫描到pos即可。
代码如下:
/** * 改进方式二: * 记录下最后一次执行交换的位置为lastpos,下一趟排序之时,lastpos之后的数都是有序的,所以下一趟 * 排序只需要到lastpos的位置就可以了 * @param args */ public void bubbleSort3(int[] array){ int lastpos = array.length - 1; int lastposTemp = array.length - 1; for(int i=0; i<array.length-1; i++){ lastpos = lastposTemp; for(int j=0; j<lastpos; j++){ if(array[j] > array[j+1]){ swap(array,j,j+1); lastposTemp = j; } } if(lastpos == lastposTemp){ break; } } }
3).传统的冒泡中每一趟排序操作只能找到一个最大值或最小值,我们可以考虑每趟排序中进行正向和反向两遍冒泡的方法一次可以得到两个最终值(最大值或最小值),从而使排序趟数几乎减少一半。
二、快速排序(Quick Sort)
基本思想:选择一个标准元素,通常选择第一个或者最后一个,通过一趟排序将待排序的记录分割成独立的两部分,其中一部分记录的元素值均比基准元素值小,另一部分记录的元素值比基准元素大。此时,基准元素在其排好序后的正确位置。然后分别对这两部分记录用同样的方法继续进行排序,直到整个序列有序。
代码如下:
public class QuickSort { public void quickSort(int[] array){ qsort(array,0,array.length-1); } //递归调用 public void qsort(int[] array, int low, int high){ int pivot; if(low < high){ pivot = partition(array, low, high); qsort(array, low, pivot-1); qsort(array, pivot+1, high); } } //先寻找一个基准元素 public int partition(int[] array, int low, int high){ int pivotkey = array[low]; while(low < high){ while(low < high && array[high]>=pivotkey){ high --; } int temp1 = array[low]; array[low] = array[high]; array[high] = temp1; while(low < high && array[low]<=pivotkey){ low ++; } int temp2 = array[low]; array[low] = array[high]; array[high] = temp2; } return low; } }
快速排序是通常被认为在同数量级O(nlogn)的排序方法中平均性能最好的,但若初始序列按关键字码有序或基本有序时,快速排序反而蜕化为冒泡排序O(n^2)。