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=======