递归:
概念:以编程的角度来看,递归是指在方法定义中调用方法本身的现象
1----100相加,使用递归完成
public static void main(String[] args) {
int sum = getSum(100);
System.out.println(sum);
}
public static int getSum(int i) {
//出口条件
if (i == 1) {
return 1;
//递归规则
} else {
return i + getSum(i - 1);
}
}
递归解题思路:
把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解
递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算
递归的设计需要两点:
一:递归的出口:没有出口条件可能会造成内存溢出
二:递归规则:与原问题相似的规模较小的问题
递归实现阶乘
public static void main(String[] args) {
int result = getJc(5);
System.out.println(result);
}
public static int getJc(int i) {
if (i == 1) {
return 1;
} else {
return i * getJc(i - 1);
}
}
递归实现阶乘内存图
执行流程就是不断的调用自己,直到参数为出口值的时候,再依次将方法弹栈,最终将结果返回
快速排序:十大排序之一
实现思路:
以基准数为准
出口:左索引值 大于 右索引值 递归结束
一: 从右开始找比比基准数小的值(使用while循环)
二:从左开始找比基准数大的值(使用while循环)
三:交换找到的左右数据(确保循环结束后,基准数左边的都是比基准数小的,右边都是比基准数大的)
四:循环继续,直到左边索引和右边索引相等为止,循环结束
五:基准数归位
六:继续调用该方法,参数传入 当前数组 ,最小索引 , 基准数索引 - 1
调用该方法,参数传入 当前数组 , 基准数索引 + 1 ,数组长度 - 1索引
public static void main(String[] args) {
int[] arr = {112, 34, 56, 7, 42, 4, 566, 5};
quiteSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
public static void quiteSort(int[] arr, int left, int right) {
//出口
if(left > right){
return;
}
int left0 = left;
int right0 = right;
//设置基准数为左起第一个
int baseNumber = arr[left0];
//循环条件左边索引 不等于 右边索引
while (left != right) {
//从右找比基准数小的元素
while (arr[right] >= baseNumber && right > left) {
right--;
}
//从左找比基准数大的元素
while (arr[left] <= baseNumber && right > left) {
left++;
}
//交换两元素位置确保基准数归位后基准数
//左边的都是比它小的,右边的都是比它大的
int temp = arr[left];
arr[left] = arr[right];
arr[right] = temp;
}
//循环结束后让基准数记录左右索引共同指向的索引
int temp = arr[left];
arr[left] = arr[left0];
arr[left0] = temp;
//递归规则
quiteSort(arr,left0,left - 1);
quiteSort(arr,left +1,right0);
}
二分查找:
前提条件:需要查找的数组必须是有序的且不为空。
实现步骤:这里使用升序排列
1,定义两个索引,表示查找范围,
默认min = 0 ,max = length - 1;
2,循环查找,循环条件为:min <= max;
3,设置中间索引: mid = (max + min) / 2;
4,判断mid索引的元素是否是要查找的元素,如果是范围mid索引;
5,如果需要查找的元素小于mid代表的元素,那么
min的值不变,max记录mid - 1; max = mid - 1;
6,如果需要查找的元素大于mid代表的元素,那么
max的值不变,min记录mid + 1; min = mid + 1;
7,当min > max 时,表示要查找的元素不在数组中,返回 -1;
代码实现:
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int num = 0;
int index = binarySearchForIndex(arr, num);
System.out.println(index);
}
public static int binarySearchForIndex(int[] arr, int num) {
//定义最大索引和最小索引
int max = arr.length - 1;
int min = 0;
//循环条件是最小索引小于等于最大索引。
//不明确循环次数用while
while (min <= max) {
//假设所查找的索引为中间索引
int mid = (min + max) >> 1;
if (arr[mid] > num) {
//如果当前索引元素大于目标值,
//说明元素在数组左边,max = mid-1;
max = mid - 1;
} else if (arr[mid] < num) {
//如果当前索引元素小于目标值,
//说明元素在数组右边,min = mid+1;
min = mid + 1;
} else {
//如果恰好在是中间值,直接返回mid即可
return mid;
}
}
//如果循环结束都没有找到索引返回-1
return -1;
}
Arrays类:
java.lang 包 所有成员方法都是静态的可以类名调用
常用的成员方法:
Arrays.toString(数组参数); 返回String类型的值
Arrays.sort(参数是数组);没有返回值,按照升序的方式排列数组,底层实现原理是快速排序
注意:binarySearch方法使用的前提条件是这个数组中的元素必须是有序排列的。
Arrays.binarySearch(参数①数组,②long 元素);传入两个参数一个是数组 另一个是long类型的被查找元素, 返回被查找元素的实际索引,如果没找到返回( 负插入点 - 1);(插入点:指当前不存在的元素应该在数组中的位置)
异常:
java.lang包
用来描述代码中出现的问题,程序出现了不正常的情况。
运行过程中,出现非正常 的情况,最终会导致JVM的非正常停止
注意:语法错误不算在异常体系中。
异常体系:Throwable 分为:
1,Error :表示严重的为题,通过代码无法处理。(如:内存溢出)
2,Exception ::指的是异常类 ,表示程序本身可以处理的问题,分为两部分:
①RuntimeExcrption以及其子类 :运行时异常,如:(空指针,索引越界等等);
②非RuntimeExcrption 之外的所有异常:编译时异常,程序运行之前必须处理的异常,否则编译不通过。
JVM虚拟机默认处理异常的方案:
把异常的名称,异常原因以及异常出现的位置等信息输出在控制台
并且停止程序运行。
异常处理的方法:
throws关键字:声明异常。写在方法的定义处。
注意:运行时异常可以不用声明异常。而编译时异常必须声明异常否则编译报错。
try{ 可能出现异常的代码…; } catch(异常对象 对象名){ 异常处理代码; }
好处:即使代码出现了运行时异常,程序也不会停止,除非捕获多个异常没有处理。
需要捕获多个异常时,需要写多个catch。。
注意:多个异常存在字父类关系那么父类一定要写在下面。否则编译报错
Throwable类
常用的成员方法:
getMessage(); 返回字符串类型throwable的详细信息
toString(); 返回字符串类型可抛出的简短描述
printStackTrace(); 把异常的错误信息输出在控制台(以红色的字体)。
**自定义异常类 **:
目的是为了让异常信息更加的见名知意
步骤:
1,定义一个异常类;
2,写继承关系(继承运行时异常类 或 非运行时异常类)
3,空参构造
4,带参构造
自定义异常代码练习
import java.util.Scanner;
public class StudentDemo {
public static void main(String[] args) {
Student stu1 = new Student();
Scanner sc = new Scanner(System.in);
System.out.println("请输入姓名:");
String name = sc.next();
stu1.setName(name);
while (true) {
try {
System.out.println("请输入年龄:");
String ag = sc.next();
int age = Integer.parseInt(ag);
stu1.setAge(age);
break;
} catch (NumberFormatException n) {
System.out.println("请输入一个正整数");
// continue;
}catch (AgeOutOfBoundsException a){
System.out.println("请输入18到25之间的数据");
//continue;
}
}
System.out.println(stu1);
}
}
class AgeOutOfBoundsException extends RuntimeException {
public AgeOutOfBoundsException() {
}
public AgeOutOfBoundsException(String message) {
super(message);
}
}
class Student {
private String name;
private int age;
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age='" + age + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age >= 18 && age <= 25) {
this.age = age;
} else {
throw new RuntimeException("请输入18到25岁之间的数值");
}
}
public Student(String name, int age) {
this.name = name;
if (age >= 18 && age <= 25) {
this.age = age;
} else {
throw new AgeOutOfBoundsException("请输入18到25岁之间的数值");
}
}
public Student() {
}
}