交换排序是根据序列中两个元素关键字的比较结果来对换这两个记录在序列中的位置。基于交换的排序算法很多,主要是冒泡排序和快速排序。
冒泡排序
冒泡排序的基本思想是:假设待排序表长为n,从前往后两两比较相邻元素的值,若为逆序(即A[i-1]>A[i]),则交换它们,直到序列比较完。我们称它为一趟冒泡,结果将最大的元素交换到待排序列的最后一个位置。下一趟冒泡时,前一趟确定的最大元素不再参与比较,待排序列减少一个元素,每趟冒泡的结果把序列中的最大元素放到序列的最终位置。这样做n-1趟冒泡就把所有的元素排好序列。
实例代码
public static void bubbleSort(int[] arr){ for(int i=0;i<arr.length-1;i++){ boolean flag = false; //设置一个标志位,如果序列本来就是由小到大排序的则直接返回 for(int j=0;j<arr.length-i-1;j++){ if(arr[j]>arr[j+1]){ int tmp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = tmp; flag = true; } } if(flag == false) //序列有序,没有发生交换,不进行排序直接返回 return; } }
快速排序
快速排序是对冒泡排序的一种改进,其基本思想是基于分治法的:在待排序表L[1…n]中任取一个元素pivot作为基准,通过一趟排序将待排序表划分为独立的两部分L[1…k-1]和L[k+1…n],使得L[1…k-1]中所有元素小于pivot,L[k+1…n]中所有元素大于或等于pivot,则pivot放在了其最终位置L(K)上,这个过程称为一趟快速排序。而后分别递归地对两个子表重复上述过程,直到每部分内只有一个元素或空为止,即所有的元素放在了最终的位置上。
示例代码
public static void quickSort(int[] arr, int low, int high){ if(low < high){ //递归结束条件 //先进行划分操作,将序列划分为两个子序列,并找出关键字的位置 int pivotpos = partition(arr, low, high); quickSort(arr, low, pivotpos-1); //对关键字左边进行排序 quickSort(arr, pivotpos+1, high); //对关键字右边进行排序 } }
partition操作是核心,需要重点理解。
private static int partition(int[] arr, int low, int high) { //在进行划分时将子序列中的第一个元素作为关键字 int pivot = arr[low]; while(low < high){ while(low < high && arr[high]>=pivot) --high; arr[low] = arr[high]; //比关键字小的移动到左端 while(low<high && arr[low] <= pivot) ++low; arr[high] = arr[low]; //比关键字大的移动到右端 } arr[low] = pivot; //关键字存放到最终的位置 return low; //返回存放的最终位置 }