关于数据结构中排序算法的总结
- 1、冒泡排序( 时间复杂度 O(n²) )
它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果他们的顺序(如从大到小、首字母从A到Z)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素已经排序完成。
/** * 冒泡排序(升序) */ public static void bubbleSort(int[] arr) { for (int i = 0; i < arr.length - 1; i++) { for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { // 交换两个值 int t = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = t; } } } }
冒泡排序其实还有改进的空间,当在某一次的走访过程中,发现并不需要交换相邻的两个值,则说明此时已经排好序了,排序直接结束。
/** * 改进后的冒泡排序(升序)
*/ public static void improveBubbleSort(int[] arr) { // 标记当前是否已经排好序了 boolean isSorted = true; for (int i = 0; i < arr.length - 1; i++) { isSorted = true; for (int j = 0; j < arr.length - 1 - i; j++) { if (arr[j] > arr[j + 1]) { // 交换两个值 int t = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = t; isSorted = false; } } if (isSorted) { return; } } }
- 2、直接选择排序( 时间复杂度 O(n²) )
它的基本思想是:第一次从R[0]~R[n-1]中选取最小值,与R[0]交换,第二次从R[1]~R[n-1]中选取最小值,与R[1]交换,....,第i次从R[i-1]~R[n-1]中选取最小值,与R[i-1]交换,.....,第n-1次从R[n-2]~R[n-1]中选取最小值,与R[n-2]交换,总共通过n-1次,
得到一个按排序码从小到大排列的有序序列。
/** * 直接选择排序(升序) */ public static void straightSelectSort(int[] arr) { // 最小元素的下标 int indexOfMin; for (int i = 0; i < arr.length; i++) { indexOfMin = i; for (int j = i + 1; j < arr.length; j++) { if (arr[j] < arr[indexOfMin]) { indexOfMin = j; } } int t = arr[indexOfMin]; arr[indexOfMin] = arr[i]; arr[i] = t; } }
- 3、直接插入排序( 时间复杂度 O(n²) )
直接插入排序是一种最简单的排序方法,其基本操作是将一条记录插入到已排好的有序表中,从而得到一个新的、记录数量增1的有序表。
/** * 直接插入排序(升序) */ public static void straightInsertSort(int[] arr) { // 待插入的元素 int insertingVal; for (int i = 1; i < arr.length; i++) { // 保存待插入的元素 insertingVal = arr[i]; int j = i - 1; while (j >= 0 && arr[j] > insertingVal) { arr[j + 1] = arr[j]; j--; } arr[j + 1] = insertingVal; } }
- 4、折半插入排序( 时间复杂度 O(n²) )
折半插入排序是对直接插入排序的一种改进,由于直接插入排序算法过程中,就是不断的依次将元素插入前面已排好序的序列中。由于前半部分为已排好序的数列,这样我们不用按顺序依次寻找插入点,可以采用折半查找的方法来加快寻找插入点的速度。
/** * 折半插入排序(升序)
*/ public static void binaryInsertSort(int[] arr) { // 待插入的元素 int insertingVal; int lowIndex, highIndex; for (int i = 1; i < arr.length; i++) { lowIndex = 0; highIndex = i - 1; // 保存待插入元素 insertingVal = arr[i]; // 二分查找待插入的位置 while (lowIndex <= highIndex) { int mIndex = (lowIndex + highIndex) / 2; if (insertingVal > arr[mIndex]) { lowIndex = mIndex + 1; } else { highIndex = mIndex - 1; } } // 开始移动元素 int j = i - 1; while (j >= lowIndex) { arr[j + 1] = arr[j]; j--; } arr[lowIndex] = insertingVal; } }