这是我参与更文挑战的第 7 天,活动详情查看: 更文挑战
-
Bubble Sort
冒泡排序是稳定的排序算法(当有相邻的两个元素大小相等的时候,我们不做交换),时间复杂度为,原地排序算法(空间复杂度为)。思想就是两个数交换顺序,一次排序至少会让一个数移到它应该在的位置,n 次肯定可以了。
代码实现如下,可以优化的点是记住最后一次交换的位置;还有就是没有交换,提前退出。
static int[] bubbleSort(int[] items, int length) { if (length <= 1){ return items; } //最后一次交换的位置,优化 int lastExchange = 0; int sortBorder = length - 1; for (int i = 0; i < length; i++) { System.out.println(items[i]); //提前退出标志位,优化 boolean flag = false; for (int j = 0; j < sortBorder; j++) { if (items[j] > items[j+1]){ swap(items,j,j+1); flag = true; lastExchange = j; } } sortBorder = lastExchange; if (!flag){ //没有数据交换,提前退出 break; } } return items; } static void swap(int[] sortItems,int a,int b){ int temp = sortItems[a]; sortItems[a] = sortItems[b]; sortItems[b] = temp; } -
Insection Sort
插入排序是原地排序算法,对于值相同的元素,我们可以选择将后面出现的元素,插入到前面出现元素的后面,这样就可以保持原有的前后顺序不变,所以插入排序是稳定的排序算法。时间复杂度。
思想就是已排序区间,未排序区间,未排序区间的元素一个个插入到已排序区间的合适位置。
这个算法不想冒泡排序那么简单粗暴(直接两两互换),因为是原地排序算法,有点类似快排的那种数组中某个值赋值给另一个值,最后还要把原先的值再赋值过来,所以写起来需要稍微注意一下,比冒泡难写多了。
public static void insertionSort(int[] a, int length) { if (length == 1) { return; } for (int i = 1; i < length; i++) { int value = a[i]; int j = i - 1; for (; j >= 0; j--) { if (a[j] > value){ a[j+1] = a[j]; } else { break; } } a[j+1] = value; //最后把 j+1 位置的值赋值为 value } }一开始取第一个数是已排序的,然后和第二个数对比,如果第一个数大于第二个数,把第二个数赋值为第一个数,然后退出内层循环,将(j+1)数赋值为第二个数;接下来已排序的是第一个,第二个数,取第三个数进行对比,如果第三个数大于第一、二个数,继续下一次循环,如果小于第二个数,参照前面,直至结束。思路理解了,就很容易写出来。
如果最后一个值最小,那么最后一次排序时,就是最后一个值要一直从尾部移动到头部。
-
Selection Sort
选择排序和插入排序挺像的,也是分已排序区间和未排序区间。但是选择排序每次会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。
选择排序是一种原地排序算法,选择排序每次都要找剩余未排序元素中的最小值,并和前面的元素交换位置,这样破坏了稳定性(因此比冒泡和插入排序稍微逊色)。最好/最坏/平均时间复杂度都为。
具体代码如下:
public static void selectionSort(int[] items, int length) { if (length <= 1) return; for (int i = 0; i < length - 1; i++) { //查找最小值 int minIndex = i; for (int j = i + 1; j < length; j++) { if (items[j] < items[minIndex]){ minIndex = j; } } //交换 swap(items,i,minIndex); } } private static void swap(int[] items,int i,int j){ int temp = items[i]; items[i] = items[j]; items[j] = temp; }