1. 快速排序
-
思想: 却低昂一个基准值,通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比基准值小,另一部分所有的数据都必基准值大,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列 。
-
图解
-
代码实现
import java.util.Arrays; public class QuickSort { public static void main(String[] args) { int[] arr = {2,10,8,22,34,5,12,28,21,11,5,12}; quickSort(arr, 0, arr.length -1); System.out.println(Arrays.toString(arr)); } public static void quickSort(int[] arr, int left, int right) { int l = left; // 左索引 int r = right; // 右索引 // 取序列中最中间的值作为基准值 int pivot = arr[(left + right) / 2]; // 将序列按照 pivot 划分为:左序列 < pivot < 右序列 int temp; while (l < r) { // 寻找左边比基准值大的数的下标 while (arr[l] < pivot) { ++l; } // 寻找右边比基准值小的数的下标 while (arr[r] > pivot) { --r; } // 如果左索引 >= 右索引,则说明已经有:左序列 < pivot < 右序列,跳出循环 if (l >= r) { break; } // 交换左右元素 temp = arr[l]; arr[l] = arr[r]; arr[r] = temp; // 如果交换完,发现 arr[l] == pivot, 后移, 防止进入死循环 if (arr[l] == pivot) { ++l; } // 如果交换完,发现 arr[r] == pivot, 前移, 防止进入死循环 if (arr[r] == pivot) { --r; } } // 如果 l == r, 必须 ++l --r, 否则为出现栈溢出 if (l == r) { ++l; --r; } // 向左递归 if (r > left) { quickSort(arr, left, r); } // 向右递归 if (l < right) { quickSort(arr, l, right); } } }
2. 归并排序
-
思想: 采用分治法的思想。对含有n个记录的表,可以看为n个有序的子表,每个子表长度为1,然后两两归并,得到 n/2 个长度为2或1的有序表,在两两合并…,依次类推。最终得到一个整体的有序表。
-
图解:
-
代码实现
import java.util.Arrays; public class MergeSort { public static void main(String[] args) { int[] arr = {2,1,4,7,5,9,8,-1,-4,-2,2,5}; int[] temp = new int[arr.length]; // 归并排序 mergeSort(arr, 0, arr.length - 1, temp); System.out.println(Arrays.toString(arr)); } /** * 归并排序算法 * @param arr 待排序序列 * @param left 左边序列的开始索引 * @param right 右边序列的最后一个元素的索引 * @param temp 临时数组,保存中间结果 */ public static void mergeSort(int[] arr, int left, int right, int[] temp) { if (left < right) { int mid = (left + right) / 2; // 左递归划分序列 mergeSort(arr, left, mid, temp); // 右递归划分序列 mergeSort(arr, mid+1, right, temp); // 归并左右两个序列 merge(arr,left,mid,right,temp); } } /** * 合并 * @param arr 待排序序列 * @param left 左边序列的开始索引 * @param mid 右边序列的前一个位置的索引 * @param right 右边序列的最后一个元素的索引 * @param temp 临时数组,保存中间结果 */ public static void merge(int[] arr, int left, int mid, int right,int[] temp){ int i = left; int j = mid + 1; int t = 0; // 比较左右两边序列,元素值小的放到temp中 while (i <= mid && j <= right) { if (arr[i] <= arr[j]) { temp[t++] = arr[i++]; } else { temp[t++] = arr[j++]; } } // 如果左边序列有剩余,则全部追加到temp中 while (i <= mid) { temp[t++] = arr[i++]; } // 如果右边序列有剩余,则全部追加到temp中 while (j <= right) { temp[t++] = arr[j++]; } // 将temp中的元素拷贝到arr中 t = 0; while (left <= right) { arr[left++] = temp[t++]; } }
-