Java-数组常见算法代码总结

数组排序(冒泡排序)

思路

1.从第一个元素开始,和相邻元素比较,如果第一个比第二个大,就交换顺序

2.然后比较第二个和第三个依次类推,一直到末尾的倒数第二位,此时数组中最大的元素换到最后一位 

 注意,不可遍历到这组元素的最后一位,最后一位没有可以和它比较的下一位元素,下标越界 

3.针对所有的元素重复以上的步骤,处理最后一个元素

4.持续每次对越来越少的元素重复上面的步骤,知道没有任何一对数字需要比较

冒泡排序的特点是,每一轮循环后,最大的一个数被交换到末尾,因此,下一次循环就可以“排除”最后的数,每一轮循环都比上一轮循环的结束位置靠前的一位

 N个数字要排序,就需要排N-1次,

 每次需要比较N-1-i次

public static void main(String[] args) {
		int[] arr= {1,3,2,5,7,10,6};
		for(int i=0;i<arr.length-1;i++) {
			for(int k=0;k<arr.length-1-i;k++) {
				if(arr[k]>arr[k+1]) {
					arr[k]=arr[k]^arr[k+1];
					arr[k+1]=arr[k]^arr[k+1];
					arr[k]=arr[k]^arr[k+1];
				}		
			}
		}
    }

 无序数组查找元素

循环遍历查找

通过对无序数组进行遍历,将数组中的每个元素与指定元素比较,从而确定该数组中是否存在指定元素。

字符串数组

	public static void main(String[] args) {
		String[] arr= {"Megatron","s司马铁锤","Laden","angelbaby","b比尔盖茨","1林平之","BIGBAM"};
		String target="s司马铁锤";
		int index=-1;
		for(int i=0,k=arr.length-1;i<arr.length;i++,k--) {
			if(arr[i].equals(target)) {
				index=i;
				break;
			}
			if(arr[k].equals(target)) {
				index=k;
				break;
			}
		}
	}

整型数组 

public class demo01 {
	public static void main(String[] args) {
		int[] array= {23,34,45,36,27,38,58,67,78,58,39};
		int target=36;//目标元素
		int index=-1;//目标元素下标,设置初始下标为-1,代表不存在
		//遍历查找
		for(int i=0;i<array.length;i++) {
			if(array[i]==target) {
				index=i;
				break;
			}
		}
		System.out.printf("目标元素%d在数组中的下标为%d",target,index);
	}
}

  字符数组

public class demo02 {
	public static void main(String[] args) {
		char[] a= {'a','b','c','d','e','f','g'};		
		char target='d';//目标元素
		int index=-1;//目标元素下标,设置初始下标为-1,代表不存在
		//遍历查找
		for(int i=0;i<a.length;i++) {
			if(a[i]==target) {
				index=i;
				break;
			}
		}
		System.out.printf("目标元素%s在数组中的下标为%d",target,index);
	}
}

 双指针遍历查找

双指针遍历的方式进行查找:通过两个下标,分别从数组头部和尾部,同时对该无序数组进行遍历,将数组中的每个元素与指定元素进行比较,从而确定该数组中是否存在指定元素。

字符串数组

public class demo01 {
	public static void main(String[] args) {
		String[] array= {"Megatron","s司马铁锤","Laden","angelbaby","b比尔盖茨","1林平之","BIGBAM"};
		String target="s司马铁锤";
		int index=-1;//目标元素下标,设置初始下标为-1,代表不存在
		//双指针查找
		for(int i=0,k=array.length-1;i<=k;i++,k--) {
			if(array[i].equals(target)) {
				index=i;
				break;
			}
			if(array[k].equals(target)) {
				index=k;
				break;
			}
		}
		System.out.printf("目标元素%s在数组中的下标为%d",target,index);
	}
}

整型数组

public class demo01 {
	public static void main(String[] args) {
		int[] array= {23,34,45,36,27,38,58,67,78,58,39};
		int target=36;//目标元素
		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.printf("目标元素%d在数组中的下标为%d",target,index);
	}
}

 字符数组

public class demo02 {
	public static void main(String[] args) {
		char[] a= {'a','b','c','d','e','f','g'};		
		char target='d';//目标元素
		int index=-1;//目标元素下标,设置初始下标为-1,代表不存在
		//双指针查找
		for(int i=0,k=a.length-1;i<=k;i++,k--) {
			if(a[i]==target) {
				index=i;
				break;
			}
			if(a[k]==target) {
				index=k;
				break;
			}
		}
		System.out.printf("目标元素%s在数组中的下标为%d",target,index);
	}
}

Arrays工具类的binarysearch()方法

通过调用Arrays.binarysearch方法,进行查找:由于该方法是基于二分查找方法实现,数组必须处于有序状态。所以,需要先对数组进行排序,再通过Arrays.binarysearch进行查找。

import java.util.Arrays;
public class e15 {
	//查找目标元素
	public static void main(String[] args) {
		int[] arr= {11,34,23,25,5,6,57};
			System.out.println("请输出一个数字");
			int target=23;
			//先使用Arrays工具类的sort方法排序
			Arrays.sort(arr);
			//再用Arrays工具类的binarySearch查找
			int index=Arrays.binarySearch(arr, target);
			System.out.printf("目标元素%d在数组中的下标为%d",target,index);
	}
}

有序数组查找元素 

二分查找元素

 二分查找思路分析

  1. 对数组进行排序,进行二分查找的数组必须是有序数组
  2. 判断中间下标元素是否与目标元素相等,若相等,直接退出
  3. 若不相等,则继续比较中间下标元素与目标元素         
  •    若中间下标元素小于目标元素,则首元素下标变为中间下标+1 ,即将当前数组的后半部分当作新的搜索数组,因为前半部分的所有元素都小于目标元素,全部排除
  •    若中间下标元素大于目标元素,尾元素下标变为中间下标-1,即将当前数组的前半部分当作新的搜索数组,因为后半部分的所有元素都大于目标元素,全部排除  

     4.在新的搜索数组上,重新开始第2步的判断  

整型数组 

import java.util.Arrays;
public class e15 {
	public static void main(String[] args) {
		//二分查找
		int[] numbers= {3,124,33,12,23,45,34,16,37,48};
		int target=12;  //目标元素
		int index=-1;   //初始目标元素下标,-1默认不存在
		//对数组进行排序
		Arrays.sort(numbers);
		System.out.println(Arrays.toString(numbers));//排序后的数组
		//定义初始首下表和尾下表
		int low=0;int high=numbers.length-1;
		while(low<=high) {
			int mid=(low+high)/2;  //计算中间下标
			if(numbers[mid]==target) { //如果中间下标元素等于目标元素,直接退出
				index=mid;
				break;
			}
			else if(numbers[mid]<target) { //如果中间下标元素小于目标元素,首元素下标变为中间下标+1
				low=mid+1;
				index=mid;
			}
			else if(numbers[mid]>target) { //如果中间下标元素大于目标元素,尾元素下标变为中间下标-1
				high=mid-1;
				index=mid;
			}
		}
		System.out.println("目标元素在数组中的下标位置:"+index);	
	}
}

字符数组 

public class R17 {
	public static void main(String[] args) {
		char[] a= {'a','b','c','d','e','f','g'};
		int low=0;int high=a.length;int index=-1;
		int target='e';
		while(low<=high) {
			int mid= (low+high)/2;
			if(a[mid]==target) {
				index=mid;
				break;
			}
			else if(a[mid]<target) {
				low=mid+1;
			}
			else if(a[mid]>target) {
				high=mid-1;
			}
		}
		System.out.println(index);
	}
}

二分查找的效率很高,是因为它在匹配不成功的时候,每次都能排除剩余元素中一半的元素。因此可能包含目标元素的有效范围就收缩的很快,而不像遍历查找那样,每次仅能排除一个元素。 

小结

  1. 查找元素可以分为两种情况:有序数组和无序数组
  2. 无序数组可以通过遍历数组或Arrays工具类两种方式查找指定元素
  3. 有序数组可以通过二分查找

数组乱序

 实现步骤

  1. 假设有一组数组numbers
  2. 从数组中最后一个元素开始遍历
  3. 设置一个随机数作为循环中遍历到的元素之前的所有元素的下标,即可从该元素之前的所有元素中随机取出一个
  4. 每次将随机取出的元素与遍历到的元素交换,即可完成乱序

实例如下: 

import java.util.Arrays;
public class R18 {
	public static void main(String[] args) {
		int[] numbers= {12,34,23,56,17,27};
		for(int k=0;k<2;k++) {
		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));
		String[] playMusicList = { "1反方向的钟", "2七里香", "3半岛铁盒", "4双节棍", "5晴天", "6青花瓷", "7一路向北", "8稻香" };
		for(int i=playMusicList.length-1;i>0;i--) {
			int index=(int)(Math.random()*i);
			 String temp=playMusicList[i];
			 playMusicList[i]=playMusicList[index];
			 playMusicList[index]=temp;
		}
		System.out.println(Arrays.toString(playMusicList));
		String[] role = { "安琪拉", "白起", "妲己", "狄仁杰", "典韦", "韩信", "老夫子", "刘禅", "鲁班七号", "墨子", "孙膑", "孙尚香", "孙悟空", "项羽",
				"亚瑟", "周瑜", "庄周", "蔡文姬" };
		for(int i=role.length-1;i>0;i--) {
			int index2=(int)(Math.random()*i);
			String temp1=role[index2];
			role[index2]=role[i];
			role[i]=temp1;
		}
		System.out.println(Arrays.toString(role));
		int[] numbers2=new int[7];	
	}	
}

代码执行结果:

[23, 17, 56, 12, 27, 34]
[2七里香, 7一路向北, 8稻香, 3半岛铁盒, 4双节棍, 5晴天, 6青花瓷, 1反方向的钟]
[墨子, 妲己, 庄周, 安琪拉, 孙膑, 周瑜, 孙尚香, 亚瑟, 老夫子, 刘禅, 韩信, 典韦, 项羽, 狄仁杰, 白起, 孙悟空, 蔡文姬, 鲁班七号]

洗牌算法

洗牌算法也是用数组乱序的方法实现 ,实例如下:

import java.util.Arrays;
public class R21 {
	public static void main(String[] args) {
		String[] num= {"A","2","3","4","5","6","7","8","9","10","j","q","k"};
		String[] num1= {"♥","♠","♦","♣"};
		String[] num3=new String[num.length*num1.length];
		String[] num4=new String[num3.length/4];
		String[] num5=new String[num3.length/4];
		String[] num6=new String[num3.length/4];
		String[] num7=new String[num3.length/4];
		int counter=0;
		int index=0;
		for(int i=0;i<num.length;i++) {
			for(int k=0;k<num1.length;k++) {
				num3[index++]=num[i]+num1[k];
			}
			
		}
		//整10次牌,即实现10次乱序
		for(int n=0;n<10;n++);{
		for(int m=0;m<num3.length-1;m++) {
			int index1=(int)(Math.random()*m);
			String temp1=num3[index1];
			num3[index1]=num3[m];
			num3[m]=temp1;
		}
			}
		for(int j=0,z=1,x=2,v=3;j<num3.length;j=j+4,z=z+4,x=x+4,v=v+4) {
			
			num4[counter]=num3[j];
			num5[counter]=num3[z];
			num6[counter]=num3[x];
			num7[counter]=num3[v];
			counter++;			
		}
		System.out.println("玩家1:"+Arrays.toString(num4));
		System.out.println("玩家2:"+Arrays.toString(num5));
		System.out.println("玩家3:"+Arrays.toString(num6));
		System.out.println("玩家4:"+Arrays.toString(num7));
	}
}

执行结果如下: 

玩家1:[10♠, j♣, 4♠, 4♣, 4♥, 6♦, 10♦, j♦, 5♥, A♦, 3♦, k♥, 10♥]
玩家2:[7♣, q♣, 2♣, 6♠, 5♣, 6♥, 9♥, q♠, 9♦, 8♥, 8♦, 7♠, A♠]
玩家3:[A♣, 3♣, 10♣, q♦, j♥, 5♦, 9♣, 7♥, 2♠, 5♠, 8♣, 2♦, 9♠]
玩家4:[k♦, 3♥, q♥, 6♣, 3♠, 7♦, 8♠, j♠, 2♥, 4♦, A♥, k♠, k♣]

数组旋转

 题目描述:

将一个数组{1,2,3,4,5,6,7}进行旋转,即将数组中所有元素向后移1位,最后一个数字放在第一位,这就完成了将数组向右旋转1位。向左旋转同理。向右旋转后的数组为{7,1,2,3,4,5,6}。

解题分析:向右旋转1位只需将数组中最后一个元素移到第1位,即从最后一个开始遍历数组,依次与前一个交换,直到交换到第1位,注意,这里的for循环只需遍历到第二位,否则下标越界。若要让数组旋转若干次,则在次循环外再加一个外层for循环,循环次数便是旋转的次数。

实例如下:

import java.util.Arrays;
public class m1 {
	public static void main(String[] args) {
		int[] ns= {1,2,3,4,5,6,7};
		for(int i=0;i<4;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];
			}	
		}
		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(Arrays.toString(ns));
	}
}

代码运行结果:

[5, 6, 7, 1, 2, 3, 4] 

import java.util.Arrays;
public class Demo01 {
	public static void main(String[] args) {
		int[] ns= {1,2,3,4,5,6,7};
		left(ns,3);
		right(ns,3);
		System.out.println(Arrays.toString(ns));

	}
	public static void left(int[] array,int w) {
		for(int k=0;k<w;k++) {
			for(int i=0;i<array.length-1;i++) {
				array[i]=array[i]^array[i+1];
			    array[i+1]=array[i]^array[i+1];
			    array[i]=array[i]^array[i+1];
			}
		}
	}
	public static void right(int[] array,int w) {
		for(int k=0;k<w;k++) {
			for(int i=array.length-1;i>0;i--) {
				array[i]=array[i]^array[i-1];
			    array[i-1]=array[i]^array[i-1];
			    array[i]=array[i]^array[i-1];
			}
		}
	}
}

 代码运行结果:

[1, 2, 3, 4, 5, 6, 7]

2.题目描述:将1奢香夫人放到最后一位 

import java.util.Arrays;
public class m2 {
	public static void main(String[] args) {
		String[] names= {"1奢香夫人","2最炫民族风","3套马的汉子","4荷塘月色","5月亮之上","6全是爱"};
		for(int k=0;k<names.length-1;k++) {		//循环
				String temp=names[k];
				names[k]=names[k+1];
				names[k+1]=temp;		
		}
		System.out.println(Arrays.toString(names));
	}
}

代码运行结果:

[2最炫民族风, 3套马的汉子, 4荷塘月色, 5月亮之上, 6全是爱, 1奢香夫人]
 

  • 45
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值