冒泡排序

83 阅读1分钟

下面我们来进行冒泡排序,它的原理就像小鱼吐泡泡,依次相邻的进行比较,将最大的向上交换 时间复杂度是O(N^2),空间复杂度是O(1),稳定。

图片的直观展示:

bubble.gif

相关的代码:

    public static void main(String[] args) {
        int[] nums = new int[]{2,0,5,1,3,7};
        bubbleSort(nums);
        for (int i = 0; i < nums.length; i++){
            System.out.println(nums[i]);
        }
    }
    //核心代码,相邻的进行比较,大的向上调
    public static void bubbleSort(int[] arr){
        if(arr == null || arr.length < 2){
         return;
        }
        //每一轮都选出了最大的放到该轮最后面,下一轮范围就除去该轮最后面的数字
        for(int i = arr.length - 1; i > 0; i--){
            for(int j = 0; j < i; j++){
                if(arr[j] > arr[j+1]){
                    //因为相等的不用交换,所以保持了稳定性
                    swap(arr,j,j+1);
                }
            }
        }
    }
    public static void swap(int[] arr, int i, int j){
        int tmp = arr[i];
        arr[i] = arr[j];
        arr[j] = tmp;
    }

对于上面的交换swap函数还有一个比较抖机灵的做法:

    public static void swap(int[] arr, int i, int j){
        arr[i] = arr[i] ^ arr[j];
        arr[j] = arr[i] ^ arr[j];
        arr[i] = arr[i] ^ arr[j];
    }

这涉及到了异或的运算,下面是异或的一些性质:

  1. 异或相当于无进位相加
  2. 甲 ^ 0 = 甲; 甲 ^ 甲 = 0
  3. 甲 ^ 乙 = 乙 ^ 甲
  4. 甲 ^ 乙 ^ 丙 = 甲 ^ (乙 ^ 丙) 所以代码块中交换的细节如下:
    public static void swap(int[] arr, int i, int j){
        arr[i] = arr[i] ^ arr[j];  // 甲 = 甲 ^ 乙  乙 = 乙
        arr[j] = arr[i] ^ arr[j];  // 乙 = (甲 ^ 乙)^ 乙 = 甲 ^(乙 ^ 乙)= 甲 甲 = 甲 ^ 乙 
        arr[i] = arr[i] ^ arr[j];  // 甲 = 甲 ^ 乙 ^ 甲 =(甲 ^ 甲)^ 乙 = 乙
                                   // 完成交换
                                   // 当然要交换的两个数不能是同一个内存地址的,因为这样会洗成0
    }

补充一个小点:

求按位来讲的数中,最后一个1

number & (~number + 1)
或者
//获得number中最低位的1
int mask = 1;
while((number & mask) == 0) {
      mask <<= 1;
}

另外一个:

number & (number − 1)//其预算结果恰为把number的二进制位中的最低位的1变为0之后的结果
如:6 & (6-1) = 4, 6 = (110), 4 = (100)