zoukankan      html  css  js  c++  java
  • 非递归实现二叉树的遍历

    二叉树遍历是树的最基本算法之中的一个,是二叉树上进行其他运算之基础。

    所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每一个结点均做一次且仅做一次訪问。

    訪问结点所做的操作依赖于详细的应用问题。
    ① 前序遍历(PreorderTraversal亦称(先序遍历))
    ——訪问根结点的操作发生在遍历其左右子树之前。
    ② 中序遍历(InorderTraversal)
    ——訪问根结点的操作发生在遍历其左右子树之中(间)。
    ③ 后序遍历(PostorderTraversal)
    ——訪问根结点的操作发生在遍历其左右子树之后。
    ④ 层次遍历(LevelTraversal)

    ——訪问从根结点開始,逐层訪问

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.Stack;
    
    //二叉树的链式结构
    class TreeNode {
    	int val;
    	TreeNode left;
    	TreeNode right;
    
    	TreeNode(int x) {
    		val = x;
    	}
    }
    
    public class TestTraversalTreeNode {
    	/**
    	 * 线序遍历
    	 * 
    	 * @param root   树根
    	 * @return
    	 */
    	public static ArrayList<Integer> preorderTraversal(TreeNode root) {
    		ArrayList<Integer> result = new ArrayList<Integer>();
    		if (root == null)
    			return result;
    		Stack<TreeNode> stack = new Stack<TreeNode>();
    		stack.push(root);
    		while (!stack.isEmpty()) {
    			TreeNode t = stack.pop();
    			result.add(t.val);
    			//先检查push右结点
    			if (t.right != null) {
    				stack.push(t.right);
    			}
    			if (t.left != null) {
    				stack.push(t.left);
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 中序遍历
    	 * 
    	 * @param root   树根
    	 * @return
    	 */
    	public static ArrayList<Integer> inorderTraversal(TreeNode root) {
    		ArrayList<Integer> result = new ArrayList<Integer>();
    		if (root == null)
    			return result;
    		Stack<TreeNode> stack = new Stack<TreeNode>();
    		TreeNode p = root;
    		//假设有左结点则一直push
    		while (!stack.isEmpty() || p != null) {
    			if (p != null) {
    				stack.push(p);
    				p = p.left;
    			} else {
    				TreeNode n = stack.pop();
    				result.add(n.val);
    				p = n.right;
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 后序遍历
    	 * 
    	 * @param root  树根
    	 * @return
    	 */
    	public static ArrayList<Integer> postorderTraversal(TreeNode root) {
    		ArrayList<Integer> result = new ArrayList<Integer>();
    		if (root == null) {
    			return result;
    		}
    		Stack<TreeNode> stack = new Stack<TreeNode>();
    		stack.push(root);
    		TreeNode prev = null;// 记录当前结点的上一个结点
    		while (!stack.empty()) {
    			TreeNode curr = stack.peek();
    			// 查看当前结点是否是叶节点。是的话就訪问
    			if (prev == null || prev.left == curr || prev.right == curr) {
    				if (curr.left != null) {
    					stack.push(curr.left);
    				} else if (curr.right != null) {
    					stack.push(curr.right);
    				} else {// 当前结点是叶节点
    					stack.pop();
    					result.add(curr.val);
    				}
    				// 查看prev是否是的当前结点左结点
    			} else if (curr.left == prev) {
    				if (curr.right != null) {
    					stack.push(curr.right);
    				} else {
    					stack.pop();
    					result.add(curr.val);
    				}
    				// 查看prev是否是当前结点的右结点
    			} else if (curr.right == prev) {
    				stack.pop();
    				result.add(curr.val);
    			}
    			prev = curr;
    		}
    		return result;
    	}
    
    	/**
    	 * 层次遍历
    	 * 
    	 * @param root  树根
    	 * @return
    	 */
    	public static ArrayList<Integer> levelTraversal(TreeNode root) {
    		ArrayList<Integer> result = new ArrayList<Integer>();
    		LinkedList<TreeNode> current = new LinkedList<TreeNode>();
    		if (root != null) {
    			current.add(root);
    			result.add(root.val);
    		}
    		while (current.size() > 0) {
    			LinkedList<TreeNode> parents = current;
    			current = new LinkedList<TreeNode>();
    			for (TreeNode parent : parents) {
    				if (parent.left != null) {
    					current.add(parent.left);
    					result.add(parent.left.val);
    				}
    				if (parent.right != null) {
    					current.add(parent.right);
    					result.add(parent.right.val);
    				}
    			}
    		}
    		return result;
    	}
    
    	/**
    	 * 遍历二叉树的第k行
    	 * 
    	 * @param root 二叉树根
    	 * @param k 第k行
    	 * @return 第k行的遍历
    	 */
    	public static String findLevelList2(TreeNode root, int k) {
    		ArrayList<LinkedList<TreeNode>> result = new ArrayList<LinkedList<TreeNode>>();
    		LinkedList<TreeNode> current = new LinkedList<TreeNode>();
    		if (root != null) {
    			current.add(root);
    		}
    		int count = 0;
    		while (current.size() > 0) {
    			result.add(current);
    			if (count == k) {
    				return listToString(current);
    			}
    			count++;
    			LinkedList<TreeNode> parents = current;
    			current = new LinkedList<TreeNode>();
    			for (TreeNode parent : parents) {
    				if (parent.left != null) {
    					current.add(parent.left);
    				}
    				if (parent.right != null) {
    					current.add(parent.right);
    				}
    			}
    		}
    		return null;
    	}
    
    	/**
    	 * 链表的结点转化为字符串进行输出
    	 * @param list
    	 * @return
    	 */
    	public static String listToString(LinkedList<TreeNode> list) {
    		int[] arr = new int[list.size()];
    		int i = 0;
    		for (TreeNode node : list) {
    			arr[i] = node.val;
    			i++;
    		}
    		return Arrays.toString(arr);
    	}
    
    	public static void main(String[] args) {
    		TreeNode root = new TreeNode(1);
    		root.left = new TreeNode(2);
    		root.right = new TreeNode(3);
    		root.left.left = new TreeNode(4);
    		root.left.right = new TreeNode(5);
    		System.out.println("前序:" + preorderTraversal(root).toString());
    		System.out.println("中序:" + inorderTraversal(root).toString());
    		System.out.println("后序:" + postorderTraversal(root).toString());
    		System.out.println("顺序:" + levelTraversal(root).toString());
    		System.out.println("K序:" + findLevelList2(root, 2));
    	}
    }



  • 相关阅读:
    修改spring源码重写classloader实现项目加密
    Java验证工具类
    jsp相关基础知识
    HTTP协议详细分析
    Java获取Linux和Window系统CPU、内存和磁盘总使用率的情况
    关于Genymotion下载比较慢的解决办法
    Android Studio:Failed to resolve ***
    ActionBar设置自定义setCustomView()留有空白的问题
    Service是什么?Service又不是什么?
    Socket--Android王国的外交发言人
  • 原文地址:https://www.cnblogs.com/wgwyanfs/p/6949556.html
Copyright © 2011-2022 走看看