递归是循环方法
main方法入栈,调用一种新方法,run方法入栈
main方法入栈,run方法入栈
起初 i = 0;i++ i变为1;调用一个run方法,i++ i=2;......直到i = 10;不会输出,i = 10,return,相当于执行完毕,该执行花括号,出栈,直到main方法出栈。
递归是循环方法,而普通的for循环,while循环只是循环方法里面那一块代码。
如何实现递归:
递归本质就是:方法调用其本身
让其在方法中输出,而不是在循环体中输出。
递归出口、递归关系式
是循环它就一定有自己的关系式。
例:组数据,1 1 2 3 5 8 13 21 ... 典型的斐波那契数列
n = 10;
f(n) = f(n-1) + f(n-2)
首先写出递归出口
画出入栈:
假设n = 7,又调用当前这个run方法,左右两边调用run方法,
到n = 2时,return为1,即方法结束。出栈。结束后返回一个数值1,
即n=2变为1
把其可以画为一个树
2 和 1的值返回1
然后依次往上类推,
可以发现f(7)=13。
递归出口一定放在递归表达式上边。
例:计 前n项和
求前n项和
例:求数组的前n项和
f(n) = f(arr, n-1) + arr[n] (必填项:arr, arr[n])
这是一个简单的递归方法。
递归出口:即当前值为0。
f(1) = 1;f(1) = arr[0]
快速排序:
定义两个游标,
i 指向最开始的位置,j 指针指向最后。
后边的j指针先走,去找比当前基准数小的数值,找到后停止。
找到1
前边的i指针后走,去找比当前基准数大的数值,找到后停止。
两者进行值的交换。
即1 和 7 进行交换。找到之后,继续执行上边的两步,直到两者相遇。
相遇的位置和基准数互换。
分成左右两部分,继续执行,左右两边都执行同一块逻辑,
找到一个数作为当前的基准数,
两者互换
继续往下 两者相遇
相遇 然后2 和 3位置互换
然后又分成两部分
找到基准数,相遇2 和 0互换
拆分
直到拆分成单个就不用拆分了
左右两部分拆分
逻辑代码
首先定义一个指针,left指向数组第一个位置;
right 永远指向最后一个位置。
往左边拆分,left不用动
当 i和 j指向同一个位置时,
拆分
递归的方式
拆成两个数组。
sort(int[] arr, int left,int right) { // left默认为0, right默认为arr.length-1;
if(left == right) { //直到相等
return;
}
sort(arr,left,i-1); //拆分成左边,right 变成了i-1;left没变。
sort(arr,i+1,right);//拆分为右边,left变为i+1,left没变
}
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] arr = {5, 7, 8, 9, 1, 4, 3, 2};
quickSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
public static void quickSort(int[] arr,int left,int right) {
if(left >= right) {
return;
}
//定义好基准数,也就是数组当中的一个数
int base = arr[left];
int i = left;
int j = right;
while(i!=j) {
while(arr[j] >= base && i<j) {//找比当前基准数>=的,直到小于base,j--
j--;
}
while(arr[i] <= base && i<j) { //找<=基准数的
i++;
}
//交换
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
//相遇之后第一个值和基准数交换
arr[left] = arr[i]; //left永远指向第一个
arr[i] = base;
quickSort(arr,left,i-1);//i-1就是当前数值-1
quickSort(arr,i+1,right);//极特殊情况下,i+1>right
}
}