JavaSE进阶17 - Arrays工具类、排序算法(冒泡+选择)、查找算法(二分法)

Arrays工具类

package com.bjpowernode.javase.array;

import java.util.Arrays;

/**
好消息:
	SUN公司已经为我们程序员写好了一个数组工具类
	java.util.Array
 */
public class ArraysTest02 {

	public static void main(String[] args) {
		
		// java.util.Arrays;工具类中有哪些方法,我们开发的时候要参考API帮助文档
		// 不要死记硬背
		
		int[] arr = {1,3,5,2,8,7};
		
		// 排序
		Arrays.sort(arr);
		
//		for(int i = 0; i < arr.length; i ++) {
//			System.out.println(arr[i]);
//		}
		
		int index = Arrays.binarySearch(arr, 80);
		System.out.println(index < 0?"元素不存在":"元素下标为:" + index);
	}
}

冒泡排序算法

package com.bjpowernode.javase.array;

/**
冒泡排序算法
	1、每一次循环结束之后,都要找到最大的数据,放到参与比较的这堆数据的最右边。(冒出最大的那个气泡)
	2、核心:
		拿着左边的数字和右边的数字比对,当左边>右边的时候,交换位置。否则位置不变。

原始数据:3,2,7,6,8
	第1次循环:(最大的跑到最右边)
	2,3,7,6,8(3和2比较,2<3,所以2和3交换位置)
	2,3,7,6,8(虽然不需要交换位置:但是3和7还是需要比较一次)
	2,3,6,7,8(7和6交换位置)
	2,3,6,7,8(虽然不需要交换位置:但是7和8还是需要比较一次)
	
	经过第1次循环,此时剩下参与比较的数据:2,3,6,7
	第2次循环:
	2,3,6,7(2和3比较,不需要交换位置)
	2,3,6,7(3和6比较,不需要交换位置)
	2,3,6,7(6和7比较,不需要交换位置)
	
	经过第2次循环,此时剩下参与比较的数据:2,3,6
	第3次循环:
	2,3,6(2和3比较,不需要交换位置)
	2,3,6(3和6比较,不需要交换位置)
	
	经过第3次循环,此时剩下参与比较的数据:2,3
	第4次循环:
	2,3(2和3比较,不需要交换位置)

 */
public class BubbleSort {
	public static void main(String[] args) {
		
		int[] arr = {9,8,10,7,6,0,11};
		int temp;
		
		// 7条数据循环6次,以下代码可以循环6次
		/*
		for(int i = 0; i < arr.length - 1; i ++) {
			System.out.println(i);
		}*/
		
		// 7条数据,循环6次。以下代码可以循环6次。(冒泡排序的外层循环采用这种方式)
		int count = 0;
		for(int i = arr.length - 1; i > 0; i --) {
			for(int j = 0; j < i; j ++) {
				count ++;
				if(arr[j] > arr[j+1]) {
					// 交换位置
					temp = arr[j];
					arr[j] = arr[j+1];
					arr[j+1] = temp;
				}
			}
		}
		
		// 遍历数组
		for(int i = 0; i < arr.length; i ++) {
			System.out.println(arr[i]);
		}
		System.out.println("比较的次数:" + count);
		
	}
}



选择排序算法

package com.bjpowernode.javase.array;

/**
选择排序:
	每一次从这堆“参与比较的数据当中”找出最小值
	拿着这个最小值和“参与比较的这堆最前面的数据”交换位置
	
	选择排序比冒泡排序的效率高:每一次的交换位置都是有意义的。
	
	参与比较的数据:3 1 6 2 5(这一堆参加比较的数据中最左边的元素下标是0)
	第1次循环之后的结果是:
	1 3 6 2 5
	
	参与比较的数据:3 6 2 5(这一堆参加比较的数据中最左边的元素下标是1)
	第2次循环之后的结果是:
	2 6 3 5
	
	参与比较的数据:6 3 5(这一堆参加比较的数据中最左边的元素下标是2)
	第3次循环之后的结果是:
	3 6 5
	
	参与比较的数据:6 5(这一堆参加比较的数据中最左边的元素下标是3)
	第4次循环之后的结果是:
	5 6
	
	最后排序结果:1 2 3 5 6
	
	注意:5条数据,循环4次。
	
	关键点:选择排序中的关键在于,怎么找出一堆数据中最小的。
		3 2 6 1 5
		假设第一个数是最小值,依次和后续数据比较,小于的替换最小值
 */
public class SelectSort {

	public static void main(String[] args) {
		
		int[] arr = {3,1,6,2,5};
		
		// 选择排序
		// 5条数据,外层循环4次
		for(int i = 0; i < arr.length - 1; i ++) {
			// i的值是0 1 2 3
			// i正好是"参加比较的这堆数据中"最左边元素的下标
			
			// 假设起点i下标位置上的元素是最小的。
			int min = i;
			
			for(int j = i + 1; j < arr.length; j ++) {
				if(arr[j] < arr[min]) {
					min = j;  //最小值的元素下标是j
				}
			}
			// 当i和min相等时,表示最初的猜测是对的。
			// 当i和min不相等时,表示最初的猜测是错误的,有比这个元素更小的元素
			// 需要拿这个更小的元素和最左边的元素交换出位置
			if(min != i) {
				// 代表存在更小的值
				// arr[min]最小的值
			    // arr[i]最左边的值
				int temp;
				temp = arr[min];
				arr[min] = arr[i];
				arr[i] = temp;
			}
		}
		
		
		// 遍历数据
		for(int i = 0; i < arr.length; i ++) {
			System.out.println(arr[i]);
		}
	}

}

二分法查找算法

package com.bjpowernode.javase.array;

/**
	1、数组工具类:自己写的。不是SUN的
	
	2、关于查找算法中的:二分查找
		10(下标是0) 11 12 13 14 15 16 17 18 19 20(下标是10)  arr数组
		
		通过二分法查找,找出18这个元素的下标:
			(0 + 10)/  2  ----> 中间元素的下标:5
			
		拿着中间这个元素的目标和要查找的元素进行对比:
			中间元素是:arr[5] --> 15
			15 < 18
			被查找的元素18在中间元素15的右边。
			所以开始元素的下标从0变成5 + 1
		
		再重新计算一个中间元素的下标:
			开始下标是:5 + 1
			结束下标是:10
			(6 + 10) / 2 --> 8
			
			8下标对应的元素是arr[8]是18
				找到的中间元素正好和被找到的元素18想等,表示找到了:下标为8
				
		二分法查找的终止条件:一直折半,直到中间的那个元素恰好是被查找的元素。
			
	3、二分法查找算法是基于排序的基础之上。(没有排序的数据是无法进行二分法查找的。)
 */
public class ArrayUtil {

	public static void main(String[] args) {
		int[] arr = {100,200,230,235,600,1000,2000,9999};
		
		// 找出arr这个数组中200所在的下标
		// 调用方法
		int index = ArrayUtil.binarySearch(arr,200);
		
		
		System.out.println(index == -1? "该元素不存在":"元素下标为:" + index);
	
		
	}
	
	// 从已排序的数组中查找目标元素的下标
	public static int binarySearch(int[] arr,int dest) {
		
		// 开始下标
		int begin = 0;
		// 结束下标
		int end = arr.length - 1;
		
		// 开始元素的下标只要在结束元素下标的左边,就有机会继续循环。
		while(begin <= end) {
			
			// 中间下标
			int mid = (begin + end) / 2;

			if(arr[mid] == dest) {
				return mid;
			}else if(arr[mid] < dest) {
				// 目标元素在中间值右边
				// 修改开始元素下标
				begin = mid + 1;
			}else if(arr[mid] > dest) {
				// 目标元素在中间值左边
				// 修改结束元素下标
				end = mid - 1;
			}
			
		}
		
		return -1;
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值