冒泡排序算法
算法思想
将一个乱序的数组,按照升序的顺序排列,若左边的元素大于右边的元素,则交换两个元素,直到任意两个数左边都小于右边;
时间复杂度和空间复杂度
时间复杂度
平均情况:O(n^2)
最优情况:O(n)
空间复杂度
平均情况:O(n^2)
最优情况:O(1)
代码实现
public static void sort(int[] num) {
int temp = 0;
for (int i = 0; i < num.length - 1; i++) {
for (int j = 0; j < num.length - 1 - i; j++) {
if (num[j] > num[j + 1]) {
temp = num[j];
num[j] = num[j + 1];
num[j + 1] = temp;
}
}
}
}
问题
代码效率低,每次排序时都需要遍历所有的元素
简单优化
将内存for循环的部分用位运算给替换了,降低内存消耗
if (num[j] > num[j + 1]) {
num[j + 1] ^= num[j];
num[j] ^= num[j + 1];
num[j + 1] ^= num[j];
}
优化
优化一
给每次循环添加一个flag标记,一次循环结束,若发生交换,说明数组不是完全升序排列,flag变为false;否则,全为升序排列;结束循环
public static void Sort(int[] num) {
int temp = 0;
for (int i = 0; i < num.length - 1; i++) {
//每次循环前,赋为true
boolean flag = true;
for (int j = 0; j < num.length - 1 - i; j++) {
if (num[j] > num[j + 1]) {
temp = num[j];
num[j] = num[j + 1];
num[j + 1] = temp;
//发生交换,改变flag的值
flag = false;
}
}
if (flag)
break;
}
}
问题
当遍历k次时,后面的k个数都是按升序排列的,且前面的n-k个数任意一个都是小于后面k个的任意一个; 遍历k+1至n-1次时,会继续遍历之前排好顺序的数,会降低效率;
解决
每次遍历结束后,将最后一次交换的位置,作为下次遍历的边界
public static void getSort2(int[] num) {
int temp = 0;
//最后一次交换的位置
int lastSwapIndex = 0;
//起始边界位置
int arrBoundary = num.length -1;
for (int i = 0; i < num.length -1; i++) {
boolean flag = true;
for (int j = 0; j < arrBoundary; j++) {
if (num[j] > num[j + 1]) {
temp = num[j];
num[j] = num[j + 1];
num[j + 1] = temp;
flag = false;
//将每次交换时的位置赋给lastSwapIndex
lastSwapIndex = j;
}
}
if (flag)
break;
//改变下次遍历时的边界
arrBoundary = lastSwapIndex;
}
}