【典型习题整理】数据结构与算法作业

本文详细解析了使用递归解决的三种典型算法:组合问题、汉诺塔和错位全排列。同时,介绍了链表在约瑟夫问题和多项式加减中的应用,并探讨了栈在中缀表达式转后缀表达式中的作用。通过对这些数据结构与算法的实战分析,有助于深化理解和应用。
摘要由CSDN通过智能技术生成

数据结构与算法


递归01:

题目类型描述: 找出从自然数 1, 2, …, n 中任取r个数的所有组合, 编一个递归算法。

具象理解:

       n=5;r=3时:即为从1,2,3,4,5这五个数中选取三个数(不追求顺序),共有C53 个答案。

抽象建模:

       题目要求运用递归,我们不妨设计一个方法,返回方式为void,输出方式为System.out.print(),存储结果于一个大小为3的数组(b[3])中。

分析:

       以题为例,因为是从5个数里面选取3个,那么我们的 b[2] 一定最小为3(当且仅当选1,2,3这三个数的时候。注:由于这里我们不考虑顺序,所以我们选出来的三个数依旧保留其在原数据流中的顺序)。我们可以逆序放置数据,即:先存放 b[2] 为3,然后从比3小的数里面选2个······

代码如下:

package OneWeek;

import java.util.*;
import java.io.*;

public class Combination {
   

	static int N = 5;
	static int M = 3;
	static int[] a= new int[]{
   1,2,3,4,5};
	static int[] b = new int[M];
	
	public static void main(String args[])throws IOException{
   
		/*从控制台读取数据的方式。
		String line;
		int n;int r;
		ArrayList<Integer> data=new ArrayList<>();
		InputStreamReader input=new InputStreamReader(System.in);
		BufferedReader yourcontent=new BufferedReader(input);
		System.out.println("Enter your n and r");
		System.out.println("(and use end to stop).");
		while(true){
			line=yourcontent.readLine();
			if(line.equals("end")) break;
			data.add(Integer.parseInt(line));
		}
		n=data.get(0);
		r=data.get(1);
		*/
		
		permutation(N,M);
	}
	
	public static void permutation(int n,int r){
   
		//从n个里面选r个。
		int i,j;
		for(i=r;i<=n;i++){
   
			b[r-1]=i-1;
			if(r>1) permutation(i-1,r-1);
			else{
   //当b数组排满以后开始打印结果。
				for(j=0;j<M;j++)
					System.out.print(a[b[j]]+" ");
				System.out.println();
			}
		}
	}
}

结果如下:

1 2 3
1 2 4
1 3 4
2 3 4
1 2 5
1 3 5
2 3 5
1 4 5
2 4 5
3 4 5

递归02:

题目类型描述: 打印汉诺塔

具象理解:

       我们假设一共有三个柱子,起始的5个盘都在1号柱上。

抽象建模:

       题目要求运用递归,我们不妨设计一个方法,返回方式依旧为void,输出方式为System.out.print(),打印出将几号柱最上面的盘子移动到几号柱。

分析:

       以题为例,因为是从5个盘子3个柱(一开始5个盘都在1号柱上),那么我们最先需要考虑的是先将最小的盘子放到2号柱上,然后将剩下的盘子放到3号柱上,最后将最小的盘放到3号柱,这样问题就解决了。

代码如下:

package OneWeek;

import java.util.Scanner;

public class Hanoi {
   
	
	//p1为初始盘,p3为目标盘
	public static void solve(int n,int p1,int p2,int p3){
   
		if(n==1)
			System.out.println("从"+p1+"移动到"+p3);
		else{
   
			solve(n-1,p1,p3,p2);
			System.out.println("从"+p1+"移动到"+p3);
			solve(n-1,p2,p1,p3);
		}
	}
	
	public static void main(String[] args) {
   
		/*从控制台读取n个圆盘.
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		*/
		solve(5,1,2,3);//这里直接给n赋值为5
	}
}

结果如下:

从1移动到3
从1移动到2
从3移动到2
从1移动到3
从2移动到1
从2移动到3
从1移动到3
从1移动到2
从3移动到2
从3移动到1
从2移动到1
从3移动到2
从1移动到3
从1移动到2
从3移动到2
从1移动到3
从2移动到1
从2移动到3
从1移动到3
从2移动到1
从3移动到2
从3移动到1
从2移动到1
从2移动到3
从1移动到3
从1移动到2
从3移动到2
从1移动到3
从2移动到1
从2移动到3
从1移动到3

递归03:

题目类型描述: n个数的错位全排列

具象理解:

       我们假设一共有3个数,错位全排列共有{3,1,2},{2,3,1}两种

抽象建模:

       题目要求运用递归,我们不难发现,当共有n个数的时候,前n-1个数的错位全排列由function(n-1)种,对于第n个数,当它在k(1<=k<n)位置的时候,现有两种情况:

  1. k在n位置处:除去n,k两个数,是(n-2)个数的错位全排列——function(n-2)
  2. k不在n位置处:那么就有这样的限定条件:1不在1位置,2不在2位置,······k不在n位置,······n-1不在n-1位置,所以是(n-1)个数的错位全排列——function(n-1)

代码如下:

package DislocationFullArrangement;

public class One {
   
	
	//递归解法。
	
	public static void main(String args[]){
   
		System.out.println(arrangement(5));
	}
	
	public static int arrangement(int n){
   
		if(n<=0) return -1;
		if(n==1) return 0;
		if(n==2) return 1;
		else return (n-1)*(arrangement(n-1)+arrangement(n-2));
	}
}

结果如下:

44

链表01:

题目类型描述: 约瑟夫问题

链表:

       我们假设一共有n=7个人,“死亡号码”m=5,即从第一个人开始,往后数到第5个会死,再从死的那个人开始往后数到第5个再处死(若数到第7号人,他的下一

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值