《算法设计与分析》之递归

目录

递归定义:

递归适用场景:

1、问题的定义是递归的:

2、存储数据的数据结构是递归的:

3、求解问题的方法是递归的:

递归的具体应用案例:

1、实现选择简单排序和冒泡排序:

2、 汉诺塔问题求解:

3、求解n皇后问题:


递归定义:

函数内部自己调用自己即为递归。

递归适用场景:

1、问题的定义是递归的:

如求n!,求斐波那契数列的第n项。

2、存储数据的数据结构是递归的:

如单链表,二叉树等。

3、求解问题的方法是递归的:

如汉诺塔。

递归的具体应用案例:

1、实现选择简单排序和冒泡排序:

简单选择排序定义:将整个数组分成有序区和无序区,初始时有序区为空,无序区为整个数组。每趟选择一个无序区的最小元素放入有序区中,最多进行n-1(假设数组长度为n)趟就能将数组从小到大排好序。

简单选择排序过程演示:

排序前:7        3        5        9        4        2

第一趟排序:2        3        5        9        4        7

第二趟排序:2        3        5        9        4        7

第三趟排序:2        3        4        9        5        7

第四趟排序:2        3        4        5        9        7

第五趟排序:2        3        4        5        7        9

简单排序算法展示(java):

package test;

public class Test {
	public static void main(String[] args) {
		int[] a= {7,3,5,9,4,2};
		sort(a,0);
		for(int i=0;i<a.length;i++)
			System.out.println(a[i]);
	}
	private static void sort(int[] nums,int start) {
		if(start==nums.length-1)
			return ;
		int min=nums[start];
		int k=start;
		for(int i=start;i<nums.length;i++)
			if(min>nums[i]) {
				min=nums[i];
				k=i;
			}
		if(k!=start) {
			int temp=nums[start];
			nums[start]=nums[k];
			nums[k]=temp;
		}
		sort(nums,start+1);
	}
}

冒泡排序定义:每趟排序只比较相邻的两个元素,小的放在前面,大的放在后面。最多进行n-1趟排序。

冒泡排序过程演示:

排序前:7        3        5        9        4        2

第一趟排序:3        5        7        4        2        9

第二趟排序:3        5        4        2        7        9

第三趟排序:3        4        2        5        7        9

第四趟排序:3        2        4        5        7        9

第五趟排序:2        3        4        5        7        9

冒泡排序算法展示:

package test;

public class Test {
	public static void main(String[] args) {
		int[] a= {7,3,5,9,4,2};
		sort(a);
		for(int i=0;i<a.length;i++)
			System.out.println(a[i]);
	}
	private static void sort(int[] nums) {
		boolean exchange=false;	//exchange用于判断数组nums是否已经有序,为退出递归的条件
		for(int i=0;i<nums.length-1;i++) {
			if(nums[i]>nums[i+1]) {
				exchange=true;
				int temp=nums[i];
				nums[i]=nums[i+1];
				nums[i+1]=temp;
			}
		}
		if(exchange)
			sort(nums);
	}
}

2、 汉诺塔问题求解:

问题描述:设有3个分别命名为x,y和z的塔座,在塔座x上有n个直径各不相同、从小到大依次编号为1~n的盘片,现要求将x塔座上的n个盘片移到塔座z上并按同样的顺序叠放。要求:1、每次只能移动一个盘片;2、盘片可以插在x,y和z中的任一塔座;3、任何时候都不能将一个较大的盘片放在较小的盘片上;4、输出移动的具体过程。

代码及注释展示:

package test;

public class Test2 {
	public static void main(String[] args) {
		char A='x',B='y',C='z';
		move(A,B,C,3);//move方法将A上的3个盘片都移动到C上
	}
	static int count=0;
	private static void move(char A,char B,char C,int n) {
		if(n==1)//如果刚好只有一个盘片,则直接移动
			System.out.println("第"+ ++count+"步:"+A+"->"+C);
		else {//如果不止一个盘片,则先将A上的n-1个盘片移动到B上,
			//再将A上剩余的一个盘片移动到C上,最后将B上的n-1个盘片移动到C上
			move(A,C,B,n-1);
			System.out.println("第"+ ++count+"步:"+A+"->"+C);
			move(B,A,C,n-1);
		}
		return ;
	}
}

3、求解n皇后问题:

LeetCode 第51题 N皇后

完整代码展示:

package leetcode_7;

import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

public class T_51 {
	static int[] q=new int[10];
	public static void main(String[] args) {
		System.out.println(solveNQueens(4));
	}
	public static List<List<String>> solveNQueens(int n) {
		List<List<String>> ans=new LinkedList();
		f(0,n,ans);
		return ans;
	}
	private static void f(int i,int n,List<List<String>> ans) {
		if(i>=n) {
			List<String> p=new LinkedList();
			for(int j=0;j<n;j++) {
				char[] ch=new char[n];
				Arrays.fill(ch, '.');
				ch[q[j]]='Q';
				p.add(new String(ch));
			}
			ans.add(p);
			return ;
		}
		for(int j=0;j<n;j++) {
			if(place(i,j)) {
				q[i]=j;
				f(i+1,n,ans);
			}
		}
	}
	private static boolean place(int i,int j) {
		if(i==0)
			return true;
		int k=0;
		while(k<i) {
			if((q[k]==j)||(Math.abs(k-i)==Math.abs(j-q[k])))
				return false;
			k++;
		}
		return true;
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值