【数据结构与算法】同种算法分别用递归/回溯与栈实现

一、阶乘

import java.util.Stack;

public class Main {

	public static int fact1(int n) {
		if (n == 0) return 1;
		else return n * fact1(n-1);
	}

	public static int fact2(int n) {
		int ans = 1;
		Stack<Integer> stack = new Stack<>();
		while (n >= 1) {
			stack.push(n);
			n--;
		}
		while (!stack.isEmpty()) {
			ans *= stack.pop();
		}
		return ans;
	}

	public static void main(String[] args) {
		int n = 3;
		System.out.println(fact1(n));
		System.out.println(fact2(n));
	}

}

二、生成环形链表

生成环形链表

import java.util.Stack;

public class Main {

	private static class Node {

		int data;
		Node next;
		Node prev;

		@Override
		public String toString() {
			StringBuilder sb = new StringBuilder();
			Node cur = this;
			for (int i = 0; i < 2 * data + 3; i++) {
				sb.append(cur.data).append(' ');
				cur = cur.next;
			}
			return sb.toString();
		}

		public Node(int data, Node next, Node prev) {
			this.data = data;
			this.next = next;
			this.prev = prev;
		}

		public Node(int data) {
			this.data = data;
		}

	}

	public static Node getCircleNode1(int data) {
		Node node = new Node(data);
		if (data == 1) {
			node.next = node;
			node.prev = node;
		} else {
			Node head = getCircleNode1(data-1);
			Node rear = head.prev;
			node.next = head;
			node.prev = rear;
			rear.next = node;
			head.prev = node;
		}
		return node;
	}

	public static Node getCircleNode2(int data) {
		Node head = new Node(1);
		head.next = head;
		head.prev = head;
		Stack<Integer> stack = new Stack<>();
		while (data > 1) {
			stack.push(data);
			data--;
		}
		while (!stack.isEmpty()) {
			Node rear = head.prev;
			Node node = new Node(stack.pop(), head, rear);
			rear.next = node;
			head.prev = node;
			head = node;
		}
		return head;
	}

	public static void main(String[] args) {
		int n = 6;
		System.out.println(getCircleNode1(n));
		System.out.println(getCircleNode2(n));
	}

}

三、二叉树的遍历

  先写一个树:

import java.util.LinkedList;
import java.util.Queue;

public class TreeNode {

	int val;
	TreeNode left;
	TreeNode right;
	
	@Override
	public String toString() {
		return "" + val;
	}	

	public TreeNode(int val) {
		this.val = val;
	}

	public TreeNode(int val, TreeNode left, TreeNode right) {
		this.val = val;
		this.left = left;
		this.right = right;
	}

	public TreeNode(Integer[] arr) {
		int i=0;
		if (arr[0] == null) throw new IllegalArgumentException();
		this.val = arr[i];
		Queue<TreeNode> queue = new LinkedList<>();
		queue.offer(this);
		while (!queue.isEmpty()) {
			int count = queue.size();
			while (count > 0) {
				TreeNode node = queue.poll();
				count--;
				i++;
				if (arr[i] != null) {
					node.left = new TreeNode(arr[i]);
					queue.add(node.left);
				}
				i++;
				if (arr[i] != null) {
					node.right = new TreeNode(arr[i]);
					queue.add(node.right);
				}
			}
		}
	}

}
1.前序遍历:
import java.util.Stack;

public class Main {

	public static void preorderTraversal1(TreeNode root) {
		if (root != null) {
			System.out.print(root + " ");
			preorderTraversal1(root.left);
			preorderTraversal1(root.right);
		}
	}

	public static void preorderTraversal2(TreeNode root) {
		Stack<TreeNode> stack = new Stack<>();
		while (root != null || !stack.isEmpty()) {
			while (root != null) {
				System.out.print(root.val + " ");
				stack.add(root);
				root = root.left;
			}
			root = stack.pop().right;
		}
		System.out.println();
	}

	public static void main(String[] args) {
		TreeNode root = new TreeNode(new Integer[]{1, 2, 3, null, 4, null, null, null, null});
		preorderTraversal2(root);
		preorderTraversal1(root);
	}

}


2.中序遍历
import java.util.Stack;

public class Main {

	public static void inorderTraversal1(TreeNode root) {
		if (root != null) {
			inorderTraversal1(root.left);
			System.out.print(root + " ");
			inorderTraversal1(root.right);
		}
	}

	public static void inorderTraversal2(TreeNode root) {
		Stack<TreeNode> stack = new Stack<>();
		while (root != null || !stack.isEmpty()) {
			while (root != null) {
				stack.push(root);
				root = root.left;
			}
			TreeNode temp = stack.pop();
			System.out.print(temp + " ");
			root = temp.right;
		}
		System.out.println();
	}

	public static void main(String[] args) {
		TreeNode root = new TreeNode(new Integer[]{1, 2, 3, null, 4, null, null, null, null});
		inorderTraversal2(root);
		inorderTraversal1(root);
	}

}
3.后序遍历
import java.util.Stack;

public class Main {

	public static void postorderTraversal1(TreeNode root) {
		if (root != null) {
			postorderTraversal1(root.left);
			postorderTraversal1(root.right);
			System.out.print(root + " ");
		}
	}

	public static void postorderTraversal2(TreeNode root) {
		Stack<TreeNode> stack = new Stack<>();
		TreeNode prev = null;
		while (root != null || !stack.isEmpty()) {
			while (root != null) {
				stack.push(root);
				root = root.left;
			}
			root = stack.peek();
			if (root.right == null || root.right == prev) {
				System.out.print(root + " ");
				stack.pop();
				prev = root;
				root = null;
			} else {
				root = root.right;
			}
		}
		System.out.println();
	}

	public static void main(String[] args) {
		TreeNode root = new TreeNode(new Integer[]{1, 2, 3, null, 4, null, null, null, null});
		postorderTraversal2(root);
		postorderTraversal1(root);
	}

}

四、走迷宫

  先构造一个工具类

package com.spd;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class MazeUtils {

	public static boolean[][] readMaze(String path) {
		boolean[][] maze = null;
		try(BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(path)))) {
			int x = Integer.parseInt(br.readLine().split("=")[1]);
			int y = Integer.parseInt(br.readLine().split("=")[1]);
			maze = new boolean[x][y];
			for (int i = 0; i < x; i++) {
				char[] arr = br.readLine().toCharArray();
				for (int j = 0; j < y; j++) {
					if (arr[j] == '0') {
						maze[i][j] = false;
					} else if (arr[j] == '1') {
						maze[i][j] = true;
					} else {
						throw new MazeFormatException("迷宫文件中出现非法字符");
					}
				}
			}
		} catch (IOException e) {
			System.err.println("IO出现异常");
		} catch (NumberFormatException e) {
			throw new MazeFormatException("迷宫文件中未提供迷宫的尺寸或包含非法字符");
		} catch (IndexOutOfBoundsException e) {
			throw new MazeFormatException("迷宫实际上的尺寸与文件中提供的尺寸不符合");
		}
		return maze;
	}

	public static String getString(boolean[][] maze, boolean[][] past) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < maze.length; i++) {
			for (int j = 0; j < maze[0].length; j++) {
				if (past[i][j]) {
					sb.append('░');
				} else {
					sb.append(maze[i][j] ? '█' : '▪');
				}
			}
			sb.append('\n');
		}
		return sb.toString();
	}

	public static class MazeFormatException extends RuntimeException {
		public MazeFormatException(String massage) {
			super(massage);
		}
	}

}

  非回溯而是用栈的方法还不会写,今天先写到这里,会了再补充。

import static com.spd.MazeUtils.*;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class Main {

	static int[][] d = new int[][]{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
	static char[] ch = "UDLR".toCharArray();

	/**
	 *
	 * @param x 当前的坐标
	 * @param y 当前的坐标
	 * @param maze 迷宫
	 * @param past 走过的路线
	 * @return 返回从当前位置到迷宫终点所要走的路线
	 */
	public static List<StringBuilder> dfs(int x, int y, boolean[][] maze, boolean[][] past) {

		System.out.println(getString(maze, past));

		LinkedList<StringBuilder> list = new LinkedList<>();

		if (x == maze.length - 1 && y == maze[0].length - 1) {
			list.add(new StringBuilder(""));
			return list;
		}

		for (int i = 0; i < 4; i++) {
			if (   0 <= x + d[i][0] && x + d[i][0] < maze.length
				&& 0 <= y + d[i][1] && y + d[i][1] < maze[0].length
				&& !maze[x + d[i][0]][y + d[i][1]] && !past[x + d[i][0]][y + d[i][1]])
			{
				past[x + d[i][0]][y + d[i][1]] = true;
				List<StringBuilder> temp = dfs(x + d[i][0], y + d[i][1], maze, past);
				past[x + d[i][0]][y + d[i][1]] = false;
				for (StringBuilder sb : temp) {
					list.add(new StringBuilder().append(ch[i]).append(sb));
				}
			}
		}
		return list;
	}

	public static List<StringBuilder> dfs(String path) {
		boolean[][] maze = readMaze(path);
		boolean[][] past = new boolean[maze.length][maze[0].length];
		past[0][0] = true;
		List<StringBuilder> list =  dfs(0, 0, maze, past);
		past[0][0] = false;
		return list;
	}

	public static void main(String[] args) {
		System.out.println(dfs("maze2.mz"));
	}

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九死九歌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值