目录
1.数组排序(优化)
实现思路:其实就是冒泡排序啦
使用两层循环,外层循环控制轮数,内层循环控制一轮的次数。遍历所有元素,这里注意元素比较时每次其实是排好一个元素的位置,所以需要比较轮数为元素个数减1。如果按照升序排序,则判断k位元素是否大于k+1位元素,大于则交换位置。
//按照升序排序
int[] numbers= {1,9,5,3,7};
//外层循环控制轮数n-1轮
for(int i=0,n=numbers.length;i<n-1;i++) {
//内层循环控制一轮的次数n-1-i
for(int k=0;k<n-1-i;k++) {
if(numbers[k]>numbers[k+1]) {
//异或交换,不是所有类型都能使用
numbers[k]=numbers[k]^numbers[k+1];
numbers[k+1]=numbers[k]^numbers[k+1];
numbers[k]=numbers[k]^numbers[k+1];
如果是String[],在比较大小时使用 compareTo()或者compareToIgnoreCase() :比较字符串大小(忽略大小写Aa-Zz);在交换元素时,使用第三方元素交换。
String[] numbers= {"zz","kk","bb"};
//外层循环控制轮数n-1轮
for(int i=0,n=numbers.length;i<n-1;i++) {
//内层循环控制一轮的次数
for(int k=0;k<n-1-i;k++) {
if(numbers[k].compareTo(numbers[k+1])>0) {
//第三方变量
String temp=numbers[k];
numbers[k]=numbers[k+1];
numbers[k+1]=temp;
}
}
}
2.无序数组查找(双指针)
实现思路:使用两个下标,一个从数组头部一个从尾循环遍历数组,两个下标同时判断当前下标元素是否等于目标元素,等于返回目标元素下标。
// 双指针
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
try (Scanner input = new Scanner(System.in)) {
int target = input.nextInt();// 目标元素
int index = -1; // 目标元素下标,默认为-1,代表不存在
for (int i = 0, k = array.length - 1; i <= k; i++, k--) {
// 从头开始比较
if (array[i] == target) {
index = i;
break;
}
// 从尾开始比较
if (array[k] == target) {
index = k;
break;
}
}
System.out.println(index);
}
ps:如果是String[]数组元素比较是否相等,需要使用equals()
3.有序数组查找(二分)
实现思路:二分查找,顾名思义分为两半,但是要注意使用二分查找的数组必须有序,不然进行分半查找没有意义。
定义数组的头部下标和尾部下标,在while循环中计算中间值,根据中间值进行遍历查找。如果中间值元素等于目标元素,则返回下标值;如果中间值元素大于目标值,则在数组的前半段查找;如果中间值元素小于目标值,则在数组的后半段查找;
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
int target = 3; // 目标元素
int index = -1;
// 数组的首尾
int low = 0, high = array.length - 1;
while (low <= high) {
// 计算中间值
int mid = (low + high) >> 1;
if (array[mid] == target) {
index = mid;
break;
} else if (array[mid] > target) {
high = mid - 1;
} else if (array[mid] < target) {
low = mid + 1;
}
}
System.out.println(index);
ps:如果是String[]数组元素比较是否相等,需要使用 compareTo()
可以直接调用二分查找方法
int[] array = { 1, 2, 3, 4, 5, 6, 7 };
int target = 3; // 目标元素
// 先排序
Arrays.sort(array);
System.out.println(Arrays.toString(array));
// 再查找
int index = Arrays.binarySearch(array, target);
System.out.println(index);
4.数组乱序
实现思路:通过一个for循环从尾部遍历数组,使用随机数产生一个随机下标,将当前的下标元素和产生的随机下标的元素进行交换。
int[] number= {1,2,3,4,5,6};
for(int i=number.length-1;i>0;i--) {
int index=(int)(Math.random()*i);
number[i]=number[i]^number[index];
number[index]=number[i]^number[index];
number[i]=number[i]^number[index];
}
System.out.println(Arrays.toString(number));
同样是String[]时,交换方法不能使用异或。
5.数组旋转
向右旋转
实现思路:通过两层循环,外层循环控制旋转的位数,内层循环控制旋转方向。
如果向右旋转,则内层循环遍历从数组尾部开始,将想要旋转的元素进行与前一个元素的交换。
int[] numbers = { 1, 2, 3, 4, 5, 6 };
// 外层循环:控制旋转的位数,循环3次代表旋转3位
try (Scanner input = new Scanner(System.in)) {
int w = input.nextInt();
for (int i = 0; i < w; i++) {
// 内层循环:控制旋转的方向,每次向右旋转1位
// 向右旋转:将尾元素通过不断交换,交换至数组头部
// 遍历的方向:从尾部开始(逆序)
// 交换的双方:当前元素k与前一个元素k+1
for (int k = numbers.length - 1; k > 0; k--) {
numbers[k] = numbers[k] ^ numbers[k - 1];
numbers[k - 1] = numbers[k] ^ numbers[k - 1];
numbers[k] = numbers[k] ^ numbers[k - 1];
}
}
System.out.println(Arrays.toString(numbers));
}
向左旋转
实现思路:通过两层循环,外层循环控制旋转的位数,内层循环控制旋转方向。
如果向左旋转,则内层循环遍历从数组头部开始,将想要旋转的元素进行与后一个元素的交换。
int[] numbers = { 1, 2, 3, 4, 5, 6 };
// 外层循环:控制旋转的位数,循环3次代表旋转3位
try (Scanner input = new Scanner(System.in)) {
int w = input.nextInt();
for (int i = 0; i < w; i++) {
// 内层循环:控制旋转的方向,每次向左旋转1位
// 向左旋转:将头元素通过不断交换,交换至数组尾部
// 遍历的方向:从头部开始(顺序)
// 交换的双方:当前元素k与后一个元素k+1
for (int k = numbers.length - 1; k > 0; k--) {
numbers[k] = numbers[k] ^ numbers[k - 1];
numbers[k - 1] = numbers[k] ^ numbers[k - 1];
numbers[k] = numbers[k] ^ numbers[k - 1];
}
}
System.out.println(Arrays.toString(numbers));
}