提纲1:数组排序(优化)
数组排序是通过冒泡排序算法实现的,基本实现思路是比较相邻的元素,把小的元素往前移动,大的元素往后移动,相邻元素两两进行比较,两个元素相等的话就不实现交换,如果大元素在小元素前面,或者小元素在大元素前面,则会通过^异或运算实现交换。
代码的实现:
1)冒泡排序
public static void main(String[] args) {
//无序数组
int[]numbers= {1,2,3,4,5,6};
System.out.println(Arrays.toString(numbers));
/*
* N个数字来排序
*两两比较小(大)靠前
* 总共比较N-1轮
*比较N-1-i次---i为下标0开始index=0
*/
int counter=0;
//比较N-1轮
//n=numbers.length排列的个数n
for(int i=0,n=numbers.length;i<n-1;i++) {
//是否已经存在"有序"状态
//true代表有序
//false代表无序
boolean isSorted=true;
//比较每轮N-1-i(n表示个数)
for(int k=0;k<n-1-i;k++) {
counter++;
//相邻比较(">"升序"<"降序)
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];
isSorted=false;
}
}
if(isSorted) {
break;
}
}
System.out.println("总共比较了"+counter+"次");
System.out.println(Arrays.toString(numbers));
}
运行结果:
提纲2:无序数组查找
无序数组查找是通过双指针查找实现的基本实现思路是:使用for循环,通过两个下标,分别从数组的头部和尾部遍历该无序数组,将数组中的每个元素与指定元素进行比较,从而确定该数组中是否存在目标元素。查找到了返回该元素在数组中所在的下标,没有查找到返回-1。
public static void main(String[] args) {
//按照歌手姓名的字符长度进行升序排列
String[]singerArray= {"李荣浩","盘尼西林","王菲","鹿先森乐队","孙燕姿","G.E.M邓紫棋","方大同"};
for(int i=0, n=singerArray.length;i<n-1;i++) {
for(int k=0;k<n-1-i;k++) {
if(singerArray[k].length()>singerArray[k+1].length()) {
String temp=singerArray[k];
singerArray[k]=singerArray[k+1];
singerArray[k+1]=temp;
}
}
}
// System.out.println(Arrays.toString(singerArray));
for(String singer:singerArray) {
System.out.println(singer);
}
}
运行结果:
提纲3:有序数组查找(二分)
有序数组查找是通过二分查找(Binary Search)算法实现的,二分查找算法的基本实现思路是:
定义一个有序的数组,以及要查找的目标整数 target。
初始化 index 为 -1,用于存储找到的目标元素的下标;数组的起始下标 low=0 和 结束下标 high =(numbers.length - 1)。
使用 while 循环,条件是 low <= high。这意味着只要搜索区间不为空,就继续查找。
在每次循环中,计算中间位置 mid,它是 low 和 high 的平均值(向下取整)。
使用 if-else 语句判断中间位下标的元素是否与目标元素相等
如果 中间位置的元素 = target,则找到了目标元素,将 index 设置为 mid 并break跳出循环。
如果 中间位置的元素 < target,则目标元素在 mid 的右侧,更新 low 为 mid + 1。
如果 中间位置的元素 > target,则目标元素在 mid 的左侧,更新 high 为 mid - 1。
循环结束后,输出 index。如果找到了目标元素,index 将是目标元素在数组中的下标;如果没有找到,index 将为 -1。
public static void main(String[] args) {
//二分查找(有序数组)
int []numbers= {1,2,3,4,5,6,7,8,9};
int target=7;
int index=-1;
//数组的首+尾
int low=0,high=numbers.length-1;
while(low<=high) {
//计算当前"中间位"下标
int mid=(low+high)/2;
//判断中间位下标的元素是否与目标元素相等
if(numbers[mid]==target) {
index=mid;
break;
}else if(numbers[mid]<target) {
low=mid+1;
}else if(numbers[mid]>target){
high=mid-1;
}
}
System.out.println(index);
//1.给出数组,2.输出原始元素3.定义目标值4.下标位置给定一个-1值,满足正常走,不满足则输出-1
//5.低位是从下标零开始,高位则是长度-1;
}
运行效果:
使用Arrays工具类的bonarySearch()方法
public static void main(String[] args) {
//查找元素:使用Arrays工具类的bonarySearch()方法
//int[]numbers={11,12,13,14,17,18,19,23,27};
int[]numbers= {3,6,2,15,19,22,2,11};
int target=19;
//快速排序
Arrays.sort(numbers);
System.out.println(Arrays.toString(numbers));
//基于二分查找,要求数组必须排序
int index=Arrays.binarySearch(numbers, target);
System.out.println(index);
}
运行结果:
提纲4:数组乱序
数组乱序 的基本实现思路是:对一个打乱顺序的数组,通过for循环逆序遍历产生随机下标,从数组的最后一个元素(数组的长度-1)开始到第二个元素(i>0),设置一个随机数作为循环中遍历到的元素之前的所有元素的下标,即可从该元素之前的所有元素中随机取出一个每次将随机取出的元素与遍历到的元素交换,即可完成乱序
public static void main(String[] args) {
//产生随机播放列表
String[] playMusicList = { "1反方向的钟", "2七里香", "3半岛铁盒", "4双节棍", "5晴天", "6青花瓷", "7一路向北", "8稻香" };
for(int i=playMusicList.length-1;i>0;i--) {
int randIndex=(int)(Math.random()*i);
String temp=playMusicList[i];
playMusicList[i]=playMusicList[randIndex];
playMusicList[randIndex]=temp;
}
for(String music:playMusicList) {
System.out.println(music);
}
//System.out.println(Arrays.toString(playMusicList));
}
运行结果:
提纲5:数组的旋转
向右旋转:从数组的尾部开始遍历(逆序遍历)逐步向前移动,每次都将当前元素与其前一个元素交换(通过^异或运算实现),直到到达数组的开始位置。这样,数组就实现了向右旋转一位的效果。重复旋转,由于外层循环执行了3次,所以数组总共向右旋转了3位。
向左旋转:从数组的头部开始遍历(顺序遍历)逐步向后移动,每次都将当前元素与其后一个元素交换(通过^异或运算实现),直到到达数组的结束位置。这样,数组就实现了向左旋转一位的效果。重复旋转,由于外层循环执行了3次,所以数组总共向左旋转了3位。
public class Demo11 {
public static void main(String[] args) {
int []numbers= {1,2,3,4,5,6,7};
System.out.println("原始数组"+Arrays.toString(numbers));
//向右旋转3位
right(numbers,3);
System.out.println("右旋3位"+Arrays.toString(numbers));
//向左旋转3位
left(numbers,3);
System.out.println("左旋转3位"+Arrays.toString(numbers));
}
//向右旋转:把尾元素,通过不断交换,移动到数组的”头部“
public static void right(int[]ns,int n) {
//向右旋转几次
for(int i=1;i<=n;i++) {
//每次向右旋转一位
for(int k=ns.length-1;k>0;k--) {
ns[k]=ns[k]^ns[k-1];
ns[k-1]=ns[k]^ns[k-1];
ns[k]=ns[k]^ns[k-1];
}
}
}
//向左旋转:把头元素,通过不断交换,移动到数组的”尾部“
public static void left(int[]ns,int n) {
for(int i=1;i<=n;i++) {
for(int k=0;k<ns.length-1;k++) {
ns[k]=ns[k]^ns[k+1];
ns[k+1]=ns[k]^ns[k+1];
ns[k]=ns[k]^ns[k+1];
}
}
}
运行结果: