java基础-7

  • 冒泡排序
  • 选择排序
  • 插入排序
  • 二分法查找数值

介绍三种常用且逻辑较为简单的排序算法,以下做法中,目标顺序默认升序

冒泡排序

/*冒泡排序的基本逻辑是:
在由前向后逐步遍历数组的过程中,对比当前元素和下一个元素的大小;
	若当前元素大于下一个元素,则调换两个元素的位置;
	否则不进行操作;
需注意的是,上述操作需要多轮才能完成排序目的;
	可以直接进行上述操作多次,次数为数组容量大小,可以确保完成目的,
	但实际大部分情况不需要这么多次;
	也可以在每次操作之后进行判断,判断结果是否已满足目标,
	即本轮是否修改了元素顺序;若无则说明已完成目标
*/
int[] arr=new int[10];
for(int i=0;i<arr.length;i++){
	arr[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(arr));//输出初始数组
for(int i=0;i<arr.length;i++){
	boolean flag=false;//标记本次是否修改了数组
	for(int j=0;j<arr.length-1-i;j++){//每循环一次,从后向前数必定增加一个确定位置的元素
		if(arr[j]>arr[j+1]){//当前元素大于后一位的元素,则调换位置
			int temp=arr[j];
			arr[j]=arr[j+1];
			arr[j+1]=temp;
			flag=true;//本轮进行了修改
		}
	}
	if(!flag){//未进行修改则跳出循环
		break;
	}
}
System.out.println(Arrays.toString(arr));//输出结果

选择排序

/*选择排序的基本逻辑是:首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,
然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。
以此类推,直到所有元素均排序完毕。
*/
int[] arr=new int[10];
for(int i=0;i<arr.length;i++){
	arr[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(arr));//输出初始数组
for(int i=0;i<arr.length-1;i++){//当i完成倒数第二个元素时,排序就已完成
	int temp=arr[i];//临时变量接收i位置的元素
	int position=i;//用于记录最小值的下标
	for(int j=i+1;j<arr.length;j++){//从i之后起算,i之前的已排序完成
		if(arr[j]<temp){
			temp=arr[j];
			position=j;
		}
	}
	arr[position]=arr[i];//将i位置的元素放到标记位置
	arr[i]=temp;
}
System.out.println(Arrays.toString(arr));//输出结果

插入排序

/*插入排序的基本逻辑是:在从前向后遍历数组的过程中,认为当前元素之前的已排序完成;
拿到当前元素后,向前查找当前元素应该放置的位置。
*/
int[] arr=new int[10];
for(int i=0;i<arr.length;i++){
	arr[i]=(int)(Math.random()*100);
}
System.out.println(Arrays.toString(arr));//输出初始数组
for (int i = 1; i < arr.length; i++) {//遍历从第二个开始,到最后一个结束
	int temp=arr[i];//定义临时变量存储当前元素值
	boolean flag=true;//表示是否找到了插入位置
	for (int j = i-1; j >=0; j--) {
		if (arr[j]<=temp){//找到了插入位置
			flag=false;
			arr[j+1]=temp;//将当前元素放到查找位置的下一位
			break;
		}else {
			arr[j+1]=arr[j];//查找位置的元素后移一位
		}
	}
	if(flag){//查找结束,未找到位置说明当前元素比前面所有都小,放在首位
		arr[0]=temp;
	}
}
System.out.println(Arrays.toString(arr));//输出结果

二分法查找数值

/*二分法查找数值的基本逻辑是,将要查找的元素与数组中间的元素对比(数组需要经过排序);
若目标元素小于当前元素,则在数组前半部分查找(修改查找边界)
若目标元素大于当前元素,则在数组后半部分查找(修改查找边界)
若目标元素等于当前元素,则输出结果
上述三步多次循环,查找到最后,将目标元素与最后的元素对比,相同则找到,不相同则找不到;
*/
int[] arr={13, 15, 30, 48, 50, 60, 67, 68, 78, 79};//定义初始数组(已排序)
int num=30;//定义要查找的数字
int s=0;//定义查找范围的最小下标
int e=arr.length-1;//定义查找范围的最大下标
while(e-s!=0&&e-s!=1){//s=e或e-s=1时说明范围无法再缩小
	int mid=(s+e)/2;
	if(num>arr[mid]){
		s=mid;//改变范围的最小下标
	}else if(num<arr[mid]){
		e=mid;//改变范围的最大下标
	}else{
		System.out.println("找到了"+num+"元素,在数组中的索引为:"+mid);
		return;
	}
}
/*上面代码改变范围时,也可设置s=mid+1;e=mid-1;
因为mid位置的元素已验证,可减少循环次数,同时避免范围内剩余两个元素的情况
但是由于数组中的元素数值不连续,输入不包含的数值时可能会跳出循环(也可以在最后再加一个验证解决);
采用上面的做法可以避免不包含的数值找不到对应输出的情况,但是需要处理剩余两个元素的情况;
*/
if(num==arr[s]){
	System.out.println("找到了"+num+"元素,在数组中的索引为:"+s);
	return;
}
if(num==arr[e]){
	System.out.println("找到了"+num+"元素,在数组中的索引为:"+e);
	return;
}
System.out.println("未找到"+num+"元素");