一、选择排序
1.选择排序的思想
每轮选择当前的位置,开始找后面的较小值与该位置进行交换。
第一轮:选择当前位置,开始找后面的较小值与该位置进行交换。
5与1交换后,1就在当前位置,因此,1与后面的所有值进行比较,后面的值都大于1,所以1的位置不变。
第二轮:选择当前位置,当前位置是5,所以5与3比较,大于3,所以5与3进行交换
5与·3交换后,3就在当前位置,因此,3与后面的所有值进行比较,后面的2小于3,所以3与2进行交换
第三轮:选择当前位置,当前位置是5,所以5与3比较,大于3,所以5与三进行交换
2.选择排序的关键
确定总共需要选择几轮:数组的长度-1。
比如:数组有5个元素,只需要比4轮,就可以排序完
控制每轮从当前位置为基准,与后面元素选择几次
public static void main(String[] args) {
// 定义数组传入一组数据
int[] numbers = {4,1,2,3};
// 输出原数组内容
System.out.println("排序前"+ Arrays.toString(numbers));
// 定义外部for循环,控制选择几轮:数组长度-1
for (int i = 0; i < numbers.length -1; i++) {
// 定义内部for循环,控制选择几次:当前位置+1,也就是后一位
for (int j = i+1; j < numbers.length; j++) {
// 当前位置:numbers[i]
// 如果后面有比当前位置更小的数据,则进行交换
if (numbers[j]<numbers[i]){
// 交换位置
// 先定义一个临时变量将当前位置的数据存一下
int temp = numbers[i];
// 再将后面的数据赋值给当前的位置
numbers[i] = numbers[j];
// 最后将当前位置的数据赋值给后面的位置
numbers[j] = temp;
}
}
}
// 全部交换完成,输出排序后的数组内容
System.out.println("排序后"+Arrays.toString(numbers));
}
二、二分查找
1.基本查找
需求:
我要查找数组中的3在哪个位置索引?
如果是基本查找,就需要从第一个位置一个一个的往后找。
结论:在数据量特别大的时候,基本查找从前往后寻找的性能是很差的。
2.二分查找
二分查找性能好,前提必须是排好序的数据。
二分查找相当于每次去掉一半的查找范围。
找到元素的执行原理:
需求:
我要查找数组中的3在哪个位置索引?
二分查找会定一个位置在首,定一个位置在尾。
之后会找,首和尾的一半的位置。
然后发现数据3小于首和尾一半位置的数据,直接从左边开始找,将右边干掉
因此,尾部的位置就是:一半的位置-1.
然后,又找首和尾的一半的位置。
之后,发现数据3大于首和尾一半位置的数据,直接从右边开始找,将左边干掉。
然后,首都的位置就是:一半的位置+1
之后,又找首和尾一半的位置
然后,发现数据11大于首和尾一半位置的数据,直接从右边开始找,将左边干掉
然后,首位置就是:一半的位置+1
之后,又找首和尾一半的位置。
然后,发现数据11大于首和尾一半位置的数据,直接从右边开始找,将左边干掉。
此时,首位置就是:一半位置+1,然后发现首尾位置重合了,因此,一半的位置还是自己,但是已经是最后一次查找了,数据还是不相等
结论:二分查找正常的检索条件是首位置min<=尾位置max,但是现在是!=,因此属于找不到,元素不存在
public static void main(String[] args) {
// 定义一个数组,传入一组数据
int [] arr ={11,33,44,99,15,35};
// 二分查找的前提是排好序的数据,所以先排序
Arrays.sort(arr);
// 输出排好序的数据内容
System.out.println("排序后"+ Arrays.toString(arr));
// 调用二分查找的方法查找元素
int index1 = binarySearch(arr,15);
System.out.println("该元素的位置索引:"+index1);
int index2 = binarySearch(arr,99);
System.out.println("该元素的位置索引:"+index2);
}
// 二分查找算法的实现方法
public static int binarySearch(int[]arr,int data){
// 定义首和尾
int head =0;
int tail = arr.length -1;
// 定义循环:当首位置<=尾位置时,开始二分查询
while (head <= tail){
// 找首和尾位置的一半的位置(中间索引) 中间索引=(首索引-尾索引)/2
int midIndex = (head +tail) / 2;
// 当要找的元素大于中间索引位置的元素时
if (data > arr[midIndex]){
// 说明要找的元素在尾位置那边,更新首位置的索引 = 中间位置的索引-1
head = midIndex+1;
}else if (data < arr[midIndex]){
// 当要找的元素 小于 中间索引位置的元素时:
// 说明要找的元素在首位置那边,更新尾位置的索引 = 中间位置的索引-1
tail = midIndex-1;
}else {
// 当要找的元素等于中间索引位置元素时,说明要找的元素已经找到,返回该元素的位置索引
return midIndex;
}
}
// 循环结束,说明找不到要找的元素返回-1
return -1;
}
控制台输出结果:
总结
数组的二分查找的实现步骤是什么?
定义变量记录首和尾的位置;
使用while循环控制二分查询(条件是首位置 <= 尾位置);
循环内部获取中间元素索引(中间元素的索引 = (首位置的索引 + 尾位置的索引) / 2);
判断当前要找的元素如果大于中间位置的元素,首位置 = 中间索引 +1;
判断当前要找的元素如果小于中间位置的元素,首位置 = 中间索引 -1;
判断当要找的元素如果等于中间位置的元素,返回当前中间元素的索引;
循环结束,说明查无此元素!返回-1。