阶乘
用递归方法求阶乘
阶乘的定义 n!= 1⋅2⋅3⋯(n-2)⋅(n-1)⋅n,其中 n 为自然数,当然 0! = 1
递推关系
代码:
private static int f(int n) {
if (n == 1) {
return 1;
}
return n * f(n - 1);
}
拆解伪码如下,假设 n 初始值为 3
f(int n = 3) { // 解决不了,递
return 3 * f(int n = 2) { // 解决不了,继续递
return 2 * f(int n = 1) {
if (n == 1) { // 可以解决, 开始归
return 1;
}
}
}
}
反向打印字符串
用递归反向打印字符串,n 为字符在整个字符串 str 中的索引位置
递:n 从 0 开始,每次 n + 1,一直递到 n == str.length() - 1
归:从 n == str.length() 开始归,从归打印,自然是逆序的
递推关系
代码:
public static void reversePrint(String str, int index) {
if (index == str.length()) {
return;
}
reversePrint(str, index + 1);
System.out.println(str.charAt(index));
}
//注意:在java语言中,我们实现这个方法有两种:上面是第一种,
//第二种:我直接从这个n=3开始,也就是从str.length-1开始递归
//每次让这个n-1,当n小于0时,则退出递归。
//以上两种方法在java语言中是可以实现的,但是在C语言中这第二种方法就不行:
//如果是用C语言还是要选择第一种方法,
//因为,因为C语言中这个字符串来讲,该开始这个长度是未知的,所以一直得从0开始向后,
//什么时候到字符串的结尾了,也就是遇到特殊字符'\0',才找到到字符串尾巴,这个时候要结束递归
拆解伪码如下,假设字符串为 "abc"
void reversePrint(String str, int index = 0) {
void reversePrint(String str, int index = 1) {
void reversePrint(String str, int index = 2) {
void reversePrint(String str, int index = 3) {
if (index == str.length()) {
return; // 开始归
}
}
System.out.println(str.charAt(index)); // 打印 c
}
System.out.println(str.charAt(index)); // 打印 b
}
System.out.println(str.charAt(index)); // 打印 a
}
递归实现二分查找
public static int search(int a[],int target){
return f(a,target,0,a.length-1);
}
private static int f(int a[],int target,int i,int j){
//对于二分查找递归的结束条件:1.找到了 2.没找到
if(i>j){//没找到情况
return -1;
}
//找到的情况
int m=(i+j)>>>1;
if(target<a[m]){
return f(a,target,i,m-1);
}else if(target>a[m]){
return f(a,target,m+1,j);
}else {
return m;
}
}
递归实现冒泡排序
public static void main(String[] args) {
int a[]={6,5,4,3,2,1};
bubble(a,a.length-1);
System.out.println(Arrays.toString(a));
}
//j 代表末排序区域右边界
//在范围[0-j]内冒泡最大元素到右侧
//a-数组
private static void bubble(int a[],int j){
//当只剩下一个数时即可结束递归
if(j==0){
return;
}
int x=0;//增加x是为了减少不必要的递归
for (int i=0;i<j;i++){
if(a[i]>a[i+1]){
int t=a[i];
a[i]=a[i+1];
a[i+1]=t;
x=i; //当在每次循环中执行最后一次交换时,让x=i的索引时,此时x是处于有序与无序的分界线,
//因为最后一次交换一定是i以后的的索引一定是有序的
}
}
bubble(a,x);
}
递归实现插入排序
public static void sort(int[] a){
insertion(a,1);//初始Low的索引是在1
}
//low:未排序的初始索引
private static void insertion(int[] a,int low){
//递归的结束标志
if(low==a.length){
return;
}
int t=a[low];//存放需要插入的数字
int i=low-1;//已排序区域指针
//没有找到插入位置 i>=0:是为了防止在插入位置在索引0的情况就要结束while循环
while (i>=0&&a[i]>t){
a[i+1]=a[i];//空出插入位置
i--;
}
//找到插入位置
a[i+1]=t;
insertion(a,low+1);
}