排序算法笔记详解(上)

1、冒泡排序

package com.Mr.ZuoChengYun.sort;

/**
 * @author pshdhx
 * @date 2022-02-11 11:21
 * @Des 冒泡排序-左程云算法学习笔记
 */
public class BubbleSort {
    public static void bubbleSort(int[] arr){
        if(arr == null || arr.length < 2){
            return ;
        }
        for(int e=arr.length-1;e>0;e--){ // 0 ~ e范围上
            for(int i=0;i<e;i++){
                if(arr[i] > arr[i+1]){ //因为上边是e-1,所有此处i+1不用担心溢出的问题。
                    swap(arr,i,i+1);
                }
            }
        }
    }
    /**
     * 异或运算还可以理解为无进位相加
     * 性质:
     *  0^N = N; N^N=0;
     *  满足交换律和结合律 a^b = b^a  (a^b)^c = a^(b^c)
     *  推出性质3
     *  a=甲 b=乙:
     *  a = a ^ b
     *  b = a ^ b
     *  a = a ^ b
     *  好处:少了一个空间的占用
     *  从第二行,用第一行结论: b= (a^b)^b ==> a^0=a  所以b就变为了a;
     *  从第三行,用第一行,第二行结论: a= (a^b) ^ a ==> b^0=b  所以a就变成了b;
     *  前提:a和b在内存中是一块独立的区域,他俩的值可以一样,但必须内存不一样。
     */
    //异或运算:相同为0,不同为1;
    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];
    }
    /**
     * 面试题整理2
     */
    public static void printOddTime2(int[] arr){
        int eor = 0;
        for(int i=0;i<arr.length;i++){
            eor^=arr[i];
        }
        int rightOne = eor & (~eor +1); //提出最右边的1
        int onlyOne = 0;
        for(int cur: arr){
            if((cur & rightOne) == 0){  //if((cur & rightOne) == 1){ //也行
                onlyOne ^= cur;
            }
        }
        System.out.println(onlyOne+" "+(eor^onlyOne));
    }

}
//面试题【在一个整型数组中,1个数字出现了奇数次,其他所有数字出现了偶数次,怎么找到出现了奇数次的数】从左到右异或即可。o(n) o(1)
//面试题【在一个整型数组中,2个数字出现了奇数次,其他所有数字出现了偶数次,怎么找到出现了奇数次的数】
//  eor=a^b 肯定!=0(假设第八位是1,a和b的第八位肯定不同,一个为1,一个为0)
//  (数字1是第八位为1异或的最终结果)eor'=a or b
//  (数字2)eor^eor' ====> a^b ^(a or b)

/**
 * 冒泡排序算法是稳定的算法:每次比较,每次交换,大数后移,每一轮都能找到一个最大的数字放到最后;
 */
/**
 * 冒泡排序与选择排序最大的不同:冒泡排序是每次比较后交换;选择排序是一轮找到最小值下标后交换。
 */

2、选择排序

package com.Mr.ZuoChengYun.sort;

/**
 * @author pshdhx
 * @date 2022-02-11 11:20
 * @Des 选择排序-左程云算法学习笔记
 */
public class SelectSort {
    public static void selectSort(int[] arr){
        if(arr == null || arr.length < 2){
            return;
        }
        for(int i=0;i<arr.length;i++){  // i~N-1
            int minIndex = i;
            for(int j=i+1;j<arr.length;j++){    //i ~ N-1上找到最小值的下标
                minIndex = arr[minIndex] < arr[j] ? minIndex : j;
            }
            swap(arr,i,minIndex); //找到了最小的数字之后,就根据下标交换数值
        }
    }
    public static void swap(int[] arr,int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

/**
 * 疑问:该排序稳定吗?怎么判断的
 * minIndex = arr[minIndex] < arr[j] ? minIndex : j; 该种判断不稳定,如果相等了,minIndex就与j交换了位置;
 * minIndex = arr[minIndex] < = arr[j] ? minIndex : j; 那么此种方式呢?稳定吗?也不稳定;
 * 6、7、6、2、8,在对其进行第一遍循环的时候,会将第一个位置的6与后面的2进行交换。此时,就已经将两个6的相对前后位置改变了。因此选择排序不是稳定性排序算法。
 * 6、7、6、2、8,在对其进行第一遍循环的时候,会将第一个位置的6与第二个位置的6交换的话,这是不可能的;
 * 选择排序算法的核心是:每次排序都找出最小的数,让第一个数【最前边的数字】与其做交换,让最小的数字放到前边;
 */

3、插入排序

package com.Mr.ZuoChengYun.sort;

/**
 * @author pshdhx
 * @date 2022-02-11 14:15
 * @Des 左程云-插入排序的实现
 */
public class InsertSort {
    public static void insertSort(int arr[]){
        if(arr == null || arr.length < 2){
            return;
        }
        for(int i=1;i<arr.length;i++){ //想要0~i范围内做到有序,直接从1开始就行,因为0位置上已经做到了有序
            System.out.println("i================="+i);
            for(int j=i-1;j>=0;j--){ //从后往前比较,然后交换。 j--无所谓了,毕竟不是--j
                System.out.println("j=======
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值