Javaの学習 - データ構造 - 非再帰的及び再帰的バイナリツリートラバーサル方法

バイナリツリートラバーサル

ここに画像を挿入説明

1、ツリー構造

public static void main(String[] args) {

		// 初始化树
		TreeNode root = new TreeNode(6);
		TreeNode node1_1 = new TreeNode(2);
		TreeNode node1_2 = new TreeNode(9);
		TreeNode node2_1 = new TreeNode(7);
		TreeNode node2_2 = new TreeNode(8);
		TreeNode node2_3 = new TreeNode(3);
		TreeNode node2_4 = new TreeNode(0);
		TreeNode node3_1 = new TreeNode(2);
		TreeNode node3_2 = new TreeNode(9);

		root.setLeft(node1_1);
		root.setRight(node1_2);
		node1_1.setLeft(node2_1);
		node1_1.setRight(node2_2);
		node1_2.setLeft(node2_3);
		node1_2.setRight(node2_4);
		node2_1.setLeft(node3_1);
		node2_1.setRight(node3_2);

		// 前序遍历
		System.out.println("*************递归实现*************");
		System.out.println("前序遍历------");
		Previous_DiGui(root);

		// 中序遍历
		System.out.println("\n中序遍历------");
		Middle_DiGui(root);

		// 后序遍历
		System.out.println("\n后序遍历------");
		After_DiGui(root);

		System.out.println("\n*************非递归实现*************");
		System.out.println("前序遍历------");
		Previous_No_DiGui(root);

		// 中序遍历
		System.out.println("\n中序遍历------");
		Middle_No_DiGui(root);

		// 后序遍历
		System.out.println("\n后序遍历------");
		After_No_DiGui(root);

	}
	// 访问节点
public static void visit(TreeNode node) {
		System.out.print(node.getData() + "  ");
	}
	
class TreeNode {
	private TreeNode left;
	private TreeNode right;
	private int data;

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

	public TreeNode(int data) {
		super();
		this.data = data;
	}

	public TreeNode getLeft() {
		return left;
	}

	public void setLeft(TreeNode left) {
		this.left = left;
	}

	public TreeNode getRight() {
		return right;
	}

	public void setRight(TreeNode right) {
		this.right = right;
	}

	public int getData() {
		return data;
	}

	public void setData(int data) {
		this.data = data;
	}

}

図2に示すように、先行順走査(再帰+非再帰的)

/**
	 * 前序遍历二叉树——递归实现
	 * 
	 * @param node
	 */
	public static void Previous_DiGui(TreeNode node) {
		if (node != null) {
			visit(node);
			Previous_DiGui(node.getLeft());
			Previous_DiGui(node.getRight());
		}

	}
/**
	 * 前序遍历二叉树——非递归实现
	 * 
	 * @param node
	 */
	public static void Previous_No_DiGui(TreeNode node) {
		Stack<TreeNode> stack = new Stack<TreeNode>();
		//当节点不为空或者栈不为空的时候循环
		while (node != null || !stack.isEmpty()) {
			//依次将左节点压到栈内,知道没有左节点
			//如果节点不为空,访问节点,压到栈内,指针指向左节点。
			while (node != null) {
				visit(node);
				stack.push(node);
				node = node.getLeft();
			}
			//访问栈,弹出栈内元素,指针指向右节点
			if (!stack.isEmpty()) {
				node = stack.pop();
				node = node.getRight();
			}
		}

	}

3、INORDERトラバーサル(再帰+非再帰的)

/**
	 * 中序遍历二叉树——递归实现
	 * 
	 * @param node
	 */
	public static void Middle_DiGui(TreeNode node) {
		if (node != null) {
			Middle_DiGui(node.getLeft());
			visit(node);
			Middle_DiGui(node.getRight());
		}
	}
/**
	 * 中序遍历二叉树——非递归实现
	 * 
	 * @param node
	 */
	public static void Middle_No_DiGui(TreeNode node) {
		Stack<TreeNode> stack = new Stack<TreeNode>();
		while (node != null || !stack.isEmpty()) {
			while (node != null) {
				stack.push(node);
				node = node.getLeft();
			}
			if (!stack.isEmpty()) {
				node = stack.pop();
				visit(node);
				node = node.getRight();
			}
		}

	}

4、後順(+再帰非再帰)

/**
	 * 后序遍历二叉树——递归实现
	 * 
	 * @param node
	 */
	public static void After_DiGui(TreeNode node) {
		if (node != null) {
			After_DiGui(node.getLeft());
			After_DiGui(node.getRight());
			visit(node);
		}

	}
/**
	 * 后序遍历二叉树——非递归实现
	 * 
	 * @param node
	 */
	public static void After_No_DiGui(TreeNode node) {
		int left = 1;// 在辅助栈里表示左节点
		int right = 2;// 在辅助栈里表示右节点
		Stack<TreeNode> stack1 = new Stack<TreeNode>();
		Stack<Integer> stack2 = new Stack<Integer>();// 辅助栈,用来判断子节点返回父节点时处于左节点还是右节点。
		while (node != null || !stack1.empty()) {
			while (node != null) {// 将节点压入栈1,并在栈2将节点标记为左节点
				stack1.push(node);
				stack2.push(left);
				node = node.getLeft();
			}
			while (!stack1.empty() && stack2.peek() == right) {// 如果是从右子节点返回父节点,则任务完成,将两个栈的栈顶弹出
				stack2.pop();
				visit(stack1.pop());
			}
			if (!stack1.empty() && stack2.peek() == left) {// 如果是从左子节点返回父节点,则将标记改为右子节点
				stack2.pop();
				stack2.push(right);
				node = stack1.peek().getRight();
			}
		}
	}

}
公開された57元の記事 ウォン称賛13 ビュー1090

おすすめ

転載: blog.csdn.net/weixin_42924812/article/details/105316419