1. 时间复杂度的注意事项:当时间复杂度相同,要实际进行操作才能比较,因为算法的常数执行时间是不同的。
简单排序算法:(这几种排序算法都不受数据状态的影响)
(一)选择排序:从0位置开始,找到最小(最大)值与0位置元素交换;从1位置开始往后找剩下元素中最大(最小)元素与1位置元素交换,直到倒数第二个元素以后找出最小(最大)交换以后有序。
/**
* 选择排序
*/
public static void selectSort(int[] arr){
int len = arr.length;
if(arr == null || len < 2) return;
int minIndex = 0;
int i, j;
for(i = 0; i < len - 1; i++){ //i : 0~len-2
minIndex = i;//每轮找最小之前,把最小位置重置为i的位置
for(j = i; j < len; j++){//j : i~len-1找最小(从i开始)
minIndex = arr[minIndex] < arr[j] ? minIndex : j;
}
swap(arr, i, minIndex);
}
}
(二)插入排序:将待排序的元素插入前面的有序数列中,以第一个元素为有序序列,将第二个元素插入其中,具体的插入方式是将待排序元素从后向前依次与前面有序元素比较,如果前面有序元素比该元素大(小),交换,直到满足条件为止
/**
* 插入排序
*/
public static void insertSort(int[] arr){
for(int i = 1; i < arr.length; i++){//认为0位置有序,给1~len-1的元素插入排序
for(int j = i - 1; j >= 0 && arr[j] < arr[j + 1]; j--){
swap(arr, j, j+1);
}
}
}
(三)冒泡排序:从第一个元素开始,把最大(最小)的元素冒到数列尾部,使用的方法是相邻遇到更大(更小)的,交换。
/**
* 冒泡排序
*/
public static void bubbleSort(int[] arr){
if(arr == null || arr.length < 2) return;
for(int i = 0; i < arr.length - 1; i++){ //一共走n-1趟
for(int j = 0; j < arr.length - i - 1; j++){ //从0开始向外冒,直到(n-i-1)的位置,因为后面的i个已经排好了
if(arr[j + 1] < arr[j]){
swap(arr, j, j + 1);
}
}
}
}
异或运算
(1)^:相同为0,不同为1;也可以看成是无进位相加;结果只与参与异或运算数的个数有关,与顺序无关。
(2)性质:0^N=N;N^N=0;满足交换律和结合律;同一堆数异或与数的先后无关
(3)异或运算交换a,b的前提是a,b不在同一内存,在数组中的体现就是 i != j,否则 arr[i] = arr[j]
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
相关题目:
package record1;
public class XorPra {
/**
* 题目描述:有一个整型数组,里面有一堆数
* (1)存在一种数在数组中出现了奇数次,其余数出现了偶数次
* (2)存在两种数在数组中出现了奇数次,其余数出现了偶数次
*
* 分别求解(1)(2)中出现奇数次的数
* @param args
*/
public static void main(String[] args) {
int[] arr = new int[]{1,1,1,2,1,3,3,4,4,4,4,5,5};
// pro1(arr);
int[] arr1 = new int[]{1,1,1,2,1,3,3,4,4,4,4,5,5,6};
pro2(arr1);
}
public static void pro1(int[] arr){
int result = 0;
for(int i = 0; i < arr.length; i++){
result = result ^ arr[i];
}
System.out.println(result);
}
public static void pro2(int[] arr){
int eor = 0;
for(int i = 0; i < arr.length; i++){
eor ^= arr[i];
} //最后的eor等于a^b
int diff = eor & (~ eor + 1); //求取某个数最右边的1,(本题中是找出a与b不相同的最右边的一位)
int a = 0;
for(int i : arr){
if((diff & i) == 0) //按照不同的一位将所有数分为两组,如果i是diff位上是0的数
a ^= i; //因为分组后,该位上为0的数偶数个仍然会被异或掉,只剩下一个奇数个的数
}
int b = eor ^ a;
System.out.println(a + ", " + b);
}
}
注:使用&运算来判断某一位上是0还是1;得到某个数最右边的1方法:x & (~x + 1)