9.排序(上)
最经典、常用的排序:





1 // 冒泡排序,a 表示数组,n 表示数组大小 2 public void bubbleSort(int[] a, int n) { 3 if (n <= 1) return; 4 5 for (int i = 0; i < n; ++i) { 6 // 提前退出冒泡循环的标志位 7 boolean flag = false; 8 for (int j = 0; j < n - i - 1; ++j) { 9 if (a[j] > a[j+1]) { // 交换 10 int tmp = a[j]; 11 a[j] = a[j+1]; 12 a[j+1] = tmp; 13 flag = true; // 表示有数据交换 14 } 15 } 16 if (!flag) break; // 没有数据交换,提前退出 17 } 18 }1)冒泡排序是原地排序算法吗? 是,冒泡过程只涉及了相邻数据的操作,只需要常量级的临时空间,空间复杂度为O(1)。 2)冒泡排序是稳定的排序算法吗? 是,冒泡中,两个相等值不交换位置,所以是稳定的。 3)冒泡排序时间复杂度是多少? 最好情况下,要排序的数据已经有序,只要进行一次冒泡操作,时间复杂度为O(n)。最坏情况是刚好,倒序排列,需要进行n次冒泡,时间复杂度是O(n2)。






1 // 插入排序,a 表示数组,n 表示数组大小 2 public void insertionSort(int[] a, int n) { 3 if (n <= 1) return; 4 5 for (int i = 1; i < n; ++i) { 6 int value = a[i]; 7 int j = i - 1; 8 // 查找插入的位置 9 for (; j >= 0; --j) { 10 if (a[j] > value) { 11 a[j+1] = a[j]; // 数据移动 12 } else { 13 break; 14 } 15 } 16 a[j+1] = value; // 插入数据 17 } 18 }1)插入算法是原地排序算法吗? 是,插入排序算法运行并不需要额外的存储空间,空间复杂度为O(1)。 2)插入排序算法是稳定的排序算法吗? 是,插入排序中,值相同的元素,可以将后面出现的元素插入到前面出现的元素后面。 3)插入排序算法那的时间复杂度是多少? O(n2),最好是完全有序时,只需要遍历一次,每次比较一次就能确定插入位置,时间复杂度为O(n)。注意,这里是从尾到头遍历有序的数据。 如果数组逆序的,每次插入都相当于在数组第一个位置插入新的数据,所以需要移动大量数据,最坏情况时间复杂度为O(n2)。 数组中插入一个数据的平均时间复杂度是O(n),对于插入排序,每次插入操作都相当于在数组中插入一个数据,循环执行n次插入操作,所以平均时间复杂度为O(n2)。 选择排序(Selection Sort) 也分排序区间和位排序区间,但是每次选择排序会从未排序区间中找到最小的元素,将其放到已排序区间的末尾。

if (a[j] > a[j+1]) { // 交换 int tmp = a[j]; a[j] = a[j+1]; a[j+1] = tmp; flag = true; } 插入排序中数据的移动操作: if (a[j] > value) { a[j+1] = a[j]; // 数据移动 } else { break; }
小结


更多精彩