一、数组排序(优化)
1.基本思路
采用冒泡排序的方法:
- 比较相邻元素,小的往前移(或大的往前移),重复此操作,直至最后一个元素比完。此时最后的数字就是数组中最大的数字。
- 除了最后一个元素,对其他元素重复上述操作
总共比较N-1轮,每轮比较N-1-i次。
2.代码实现
import java.util.Arrays;
public class demo01 {
public static void main(String[] args) {
int[] arr= {4, 5, 6, 7, 1, 2, 3,8,26};
for(int i=0,n=arr.length;i<n-1;i++) {
for(int k=0;k<n-1-i;k++) {
if(arr[k]>arr[k+1]) {
//交换arr[k]和arr[k+1]
int temp=arr[k];
arr[k]=arr[k+1];
arr[k+1]=temp;
}
}
}
//排序后
System.out.println(Arrays.toString(arr));
//[1, 2, 3, 4, 5, 6, 7, 8, 26]
}
}
二、无序数组查找
采取循环遍历的方法进行无序数组的查找。
1. 基本思路
方法1:查找第一次出现目标元素的位置,利用嵌套循环。如果查找到,就返回对应下标,退出循环。
方法2:查找最后一次出现目标元素的位置。
- 思路1:利用逆序遍历(外层for循环),让每一个元素都与目标元素比较(内层if语句),如果相同,返回对应下标。
- 思路2:利用方法1,不过第一次查找到时不用跳出循环,继续查找到最后
方法3:双指针查找目标元素所在位置。一个从头开始查找(下标i=0),一个从尾部开始查找(下标k=数组长度-1),分别判断是否与目标元素相同,相同则返回对应下标,不同则继续查找。但i永远都小于等于k时,循环才能继续。
方法4:利用Arrays工具类的方法实现,先使用sort()方法对数组进行排序,再使用binarySearch()方法进行二分查找
2.代码实现
public class demo01 {
public static void main(String[] args) {
//要查找的数组
int[] arr= {2,3,56,8,25,96,3,51,24};
//目标元素
int target=25;
//定义初始下标为-1
int index=-1;
//方法一:顺序遍历整个数组
for(int i=0;i<arr.length;i++) {
//判断是否相同
if(arr[i]==target) {
//相同则下标为i
index=i;
break;
}
}
System.out.println("方法一的结果:"+index);//方法一的结果:4
//方法二:逆序遍历
for(int i=arr.length-1;i>0;i--) {
//判断是否相同
if(arr[i]==target) {
index=i;
break;
}
}
System.out.println("方法二的结果:"+index);//方法二的结果:4
//方法三:双指针查找
for(int i=0,k=arr.length-1;i<=k;i++,k--) {
if(arr[i]==target) {
index=i;
break;
}
if(arr[k]==target) {
index=k;
break;
}
}
System.out.println("方法三的结果:"+index);//方法三的结果:4
//方法四:利用Arrays工具类的方法
Arrays.sort(arr);
System.out.println("排序后的数组"+Arrays.toString(arr));
//排序后的数组[2, 3, 3, 8, 24, 25, 51, 56, 96]
index=Arrays.binarySearch(arr, target);
System.out.println("方法四的结果:"+index);//方法四的结果:5
}
}
三、有序数组查找(二分)
1.基本思路
- 定义目标数组的开始下标low和结束下标high。
- 通过while循环,计算中间下标mid=(high+low)/2。判断中间下标对应的元素和目标元素是否相同(只有当low<=high时,循环才能继续进行)
- 如果相同,则直接返回中间下标;
- 如果中间下标对应的元素大于目标元素,则说明目标元素在开始元素到中间元素之间,舍弃后半段数组,接下来再前半段数组中查找,但必须再次计算中间下标,继续按照之前步骤查找。
- 如果中间下标对应的元素小于目标元素,则说明目标元素在中间元素到末尾元素之间,舍弃前半段数组,接下来再后半段数组中查找,同样再次计算中间下标,继续按照之前步骤查找。
2.代码实现
public class demo01 {
public static void main(String[] args) {
int[] number= {1,2,3,4,5,6,7,8,9};
//定义开始下标和结束下标
int low=0,high=number.length-1;
int index=-1;
int target=7;
while(low<=high) {
//计算中间下标
int mid=(low+high)/2;
//判断中间元素是否与目标元素相同
if(number[mid]==target) {
index=mid;
break;
}else if(number[mid]>target) {//中间元素大于目标元素
//舍弃后半段数组,在前半段数组中查找
high=mid-1;
}else if(number[mid]<target) {//中间元素小于目标元素
//舍弃前半段数组,在后半段数组中查找
low=mid+1;
}
}
System.out.printf("目标元素%d的位置为%d\n",target,index);
//目标元素7的位置为6
}
}
四、数组乱序
1.基本思路
一个数组arr,随机产生一个数字,将数组arr中最后一个元素与前面元素中下标为随机数的元素交换位置。重复上面步骤,直到数组元素全部乱序。
2.代码实现
public class demo01 {
public static void main(String[] args) {
int[] numbers= {2,9,8,6,3,4,15,63};
for(int i=numbers.length-1;i>0;i--) {
//产生随机数,作为随机下标
int index=(int)(Math.random()*i);
//交换位置
numbers[index]=numbers[i]^numbers[index];
numbers[i]=numbers[i]^numbers[index];
numbers[index]=numbers[i]^numbers[index];
}
System.out.println(Arrays.toString(numbers));
//[63, 3, 9, 8, 4, 2, 6, 15]
}
}
五、数组旋转
1.基本思路
以向右旋转为例:
就是将数组的最后一位元素与前面元素依次交换,直到最后一位元素存放在首元素的位置上。这个代表向右旋转一次。如果要进行n次向右旋转,需要在外面套层循环
向左旋转同样,不过是第一位元素依次向后交换,交换到最后。
2.代码实现
import java.util.Arrays;
public class demo01 {
public static void main(String[] args) {
int[] n= {1,2,3,4,5,6,7};
//进行3次向右旋转
for(int i=0;i<3;i++) {
//进行1次向右旋转(整体向右移动,但数组长度不变)
for(int k=n.length-1;k>0;k--) {
n[k]=n[k]^n[k-1];
n[k-1]=n[k]^n[k-1];
n[k]=n[k]^n[k-1];
}
}
System.out.println("向右旋转3次:"+Arrays.toString(n));
//向右旋转3次:[5, 6, 7, 1, 2, 3, 4]
int[] ns= {1,2,3,4,5,6,7};
//进行3次向左旋转
for(int p=0;p<3;p++) {
//进行1次向左旋转(整体向左移动,但数组长度不变)
for(int m=0;m<ns.length-1;m++) {
ns[m]=ns[m]^ns[m+1];
ns[m+1]=ns[m]^ns[m+1];
ns[m]=ns[m]^ns[m+1];
}
}
System.out.println("向左旋转3次:"+Arrays.toString(ns));
//向左旋转3次:[4, 5, 6, 7, 1, 2, 3]
}
}