一.查找算法
(1)基本查找
基本查找就是一个一个遍历数组,直到找到所需元素,效率最低
(2)二分/折半查找
前提条件:数组中的数据是有序的
核心逻辑:每次去除一半的查找范围
优点:效率比基本查找要高
实现:
1.max是数组最大索引
2.min是数组最小索引
3.mid是二者的整除所取的整数,拿它来跟目标值作比较
4.如果mid索引的整数比目标值大,那么min=mid+1
5.如果比目标值小,那么max=mid-1
如果目标值不在数组中,返回索引-1,并且这时候min会大于max(因为当要找的数据大于所有数据的时候,min最后会比max大;如果要找的数据小于所有数据,max最后比min小;如果在数据之中找不到数据,min最后也会比max大;但是一般要查找的的数据都在数组里面)
public class BinarySearch {
public static void main(String[] args) {
int[] arr = {1, 22, 33, 44, 55, 6666, 77777, 88888, 99999, 100000};
System.out.println(binarySearch(arr, 22));
}
public static int binarySearch(int[] arr, int target) {
int min=0;
int max=arr.length-1;
while (true){
int mid=(min+max)/2;
if (min>max){
return -1;
}
//mid索引在目标左边
if (arr[mid]<target){
min=mid+1;
}
//mid索引在目标右边
if (arr[mid]>target){
max=mid-1;
}
//mid索引在目标上
if (arr[mid]==target){
return mid;
}
}
}
}
(3)分块查找
用于每个数据之间没有顺序,但是每个区域间有顺序的情况:
例如有个数组:{1,3,2,4,5,66,88,77,999,100,101}
(会发现每个数据之间确实是没有顺序可言,但是可以把这几个数据分区域,第一个区域的最大值为5,第二个区域最大值为88,第三个区域最大值为101,而且第二个区域的所有数据都大于第一个区域,第三个区域的数据也大于第二个区域的最大数值,那么就可以利用分块查找了。)
1.既然要分区,那我们可以先创建一个区域类:Block
class Block{
int maxIndex;
int minIndex;
int maxNumber;
还有构造方法和get,set方法等等
}
2.创建对象,把每个区域信息填进去,一般创建数据个数的平方根个对象
3.创建存放Block对象的数组
4.创建方法去把目标值的所在区域找到
5.创建方法在区域中找目标值,并返回索引
实例:
public class BlockSearch {
public static void main(String[] args) {
int[] arr = {1, 22, 34, 33, 55, 66, 78, 68, 9999, 10000};
Block b1= new Block(3, 0, 34);
Block b2= new Block(7, 4, 78);
Block b3= new Block(9, 8, 10000);
Block[] blockArr = {b1, b2, b3};
int target = 33;
int index = finalSearch(blockArr, target, arr);
System.out.println("index = " + index);
}
//先找区域
public static int blockSearch(Block[] arr,int target){
for(int i=0;i<arr.length;i++){
if(arr[i].maxNumber>=target){
return i;
}
}
return -1;
}
//再找位置
public static int finalSearch(Block[] arr1,int target,int[] arr2){
int index = blockSearch(arr1,target);
if (index==-1){
return -1;
}
for(int i=arr1[index].minIndex;i<=arr1[index].maxIndex;i++){
if (arr2[i]==target){
return i;
}
}
return -1;
}
}
//Block
class Block{
int maxIndex;
int minIndex;
int maxNumber;
public Block(int maxIndex, int minIndex, int maxNumber) {
this.maxIndex = maxIndex;
this.minIndex = minIndex;
this.maxNumber = maxNumber;
}
}
结果:
二.排序算法
(1)冒泡排序
相邻的元素两两比较,先按照要求把最大或者最小的先放到右边:
——外循环是看它要执行的次数,也就是数据数量-1次
——内循环的-1是为了不让i+1(最后一个数据)超出索引
——内循环的-i是为了效率,因为每次执行完,就可以减少最后一个数据,也就是减少一次
public class BubbleSort {
public static void main(String[] args) {
int[] arr={2,5,8,9,1,5,6,4,7,8};
for (int i=0;i<arr.length-1;i++){
for (int j=0;j<arr.length-i-1;j++){
if(arr[j]>arr[j+1]){
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
结果:
(2)选择排序
拿第一个元素跟后面的元素比,符合要求的放到一个,继续循环,让第二个元素再依次跟后面比,让符合规则的放到第二个,然后一个一个把最大的挑出来(从大到小排序)。以此类推,跟冒泡不同的是,把确定的元素放到左边
——i是用来做比较的下标
——j是比i大1,然后逐渐递增的下标的元素
下面是排序从大到小:
public class SelectionSort {
public static void main(String[] args) {
int[] arr={2,5,8,9,1,5,6,4,7,8};
//i是要拿来做比较的元素下标
for (int i=0;i<arr.length-1;i++){
for(int j=i+1;j<arr.length;j++){
if(arr[j]>arr[i]){
int temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
}
}
System.out.println(Arrays.toString(arr));
}
}
结果:
(3) 插入排序
将0索引到n索引的数据看作是有序的,把索引为n+1一直到最后一个索引当作是无序的,遍历无序的数组,将遍历到的数据插入到有序序列中的合适位置,如遇到相同数据,排在后面,这个方法就是插入排序
public class InsertSort {
public static void main(String[] args) {
//将下面的数组按照从大到小排列
int[] arr={5,8,3,2,17,19,15,16,90};
//找无序的开始索引
int startIndex=-1;
for(int i=0;i<arr.length;i++){
if(arr[i+1]>arr[i]){
startIndex=i+1;
break;
}
}
//从无序开始索引开始插入排序,反向遍历,一个一个对比插入
for(int i=startIndex;i<arr.length;i++){
int j=i;
while(j>0&&arr[j]>arr[j-1]){
int temp=arr[j];
arr[j]=arr[j-1];
arr[j-1]=temp;
j--;
}
}
//看结果
System.out.println(Arrays.toString(arr));
}
}
结果:
三.递归算法
递归指的是方法中调用方法自己本身的现象。
递归的注意点:一定要有出口,否则会内存溢出。所谓出口就是调用到第几次就不再调用自己了。
递归的作用:大事化小,小事化了
书写递归的两个核心:1.出口
2.找规则如何把大问题转换成规模较小的小问题
3.再次调用方法的时候,要更靠近出口
实例:求1——100的和
public class Recursion {
public static void main(String[] args) {
System.out.println(getSum(100));
}
public static int getSum(int number){
if(number == 1){
return 1;
}
return number + getSum(number - 1);
}
}
//其实就是把1+100转换成:
- 100+1—99的和
- 99+1—98的和
- 98+1—97的和
- 。。。
- 2+1的和
- 1就是出口