二叉树系列—二叉树遍历

1、二叉树深度与广度遍历

1.1 二叉树层次遍历

思路:
访问根节点,并将根节点入队。
当队列不空的时候,重复以下操作。
1、弹出一个元素。作为当前的根节点。
2、如果根节点有左孩子,访问左孩子,并将左孩子入队。
3、如果根节点有右孩子,访问右孩子,并将右孩子入队。

		public void levelOrder(TreeNode root) {
	    //使用队列,先进先出
	    Queue<TreeNode> queue = new LinkedList<>();
	    queue.add(root);
	    while (!queue.isEmpty()) {
	        TreeNode temp = queue.poll();
	        System.out.print(temp.val + "  ");
	        if (temp.left != null) {
	            queue.offer(temp.left);
	        }
	        if (temp.right != null) {
	            queue.offer(temp.right);
	        }
	    }
	}
	/**
     * 尾结点标记法
     *
     * @param root
     */
    public static void printTreeByLevel(Node root) {
        Queue<Node> queue = new LinkedList<>();
        queue.add(root);
        Node tail = root;
        Node tmp = root;
        while (!queue.isEmpty()) {
            Node node = queue.poll();
            if (node.left != null) {
                queue.add(node.left);
                tmp = node.left;
            }
            if (node.right != null) {
                queue.add(node.right);
                tmp = node.right;
            }
            System.out.print(node.val + " ");
            if (node == tail) {
                System.out.println();
                tail = tmp;
            }
        }
    }

1.2 深度遍历(先根遍历)

 public void deep(TreeNode root){
			 if(root==null){
				 return;
			 }
			 LinkedList<TreeNode> stack=new LinkedList<TreeNode>();
			 stack.push(root);
			 if(!stack.isEmpty()){
				 TreeNode node=stack.pop();
				 System.out.println(node.data);
				 if(node.right!=null){
					 stack.push(node.right);
				 }
				 if(node.left!=null){
					 stack.push(node.left);
				 }
			 }
	 	 }

2、二叉树非递归实现

2.1 递归遍历

	
		//前序
		public static void preTraversal(Node root){
			if(root==null)
				return ;
			System.out.println(root.value);
			preTraversal(root.left);
			preTraversal(root.right);
		}
		//中序
		public static void midTraversal(Node root){
			if(root==null)
				return;
			preTraversal(root.left);
			System.out.println(root.value);
			preTraversal(root.right);
		}
		//后序
		public static void  postTraversal(Node root){
			if(root==null)
				return;
			preTraversal(root.left);
			preTraversal(root.right);
			System.out.println(root.value);
		}

2.2 非递归

非递归通过栈来实现

  • 非递归先序
		public static void preOrder(Node root){
			if(root==null)
				return;	
			Stack<Node> stack=new Stack<Node>();
			Node node=root;
			stack.push(node);
			//出栈、输出、入右、入左
			while(!stack.isEmpty()){
				node=stack.pop();
				System.out.println(node.value);
				if(node.right!=null){
					stack.push(node.right);
				}
				if(node.left!=null){
					stack.push(node.left);
				}
			}
		}
  • 中序遍历
		  /**
	     * 二叉树的中序遍历:
	     *      遍历时会重复遍历最左子节点
	     *      因此不能一直指针指向左遍历
	     *      当左为空时,调整指针指向右节点
	     *
	     * @param root
	     */
		public void midOrder(Node root){
			if(root==null)
				return;
			Stack<Node> stack=new  Stack<Node>();
			Node node=root;
			//先将left节点全部入栈,再出栈输出,最后node指向rught节点
			while(node!=null||!stack.isEmpty()){
				if(node!=null){
					stack.push(node);
					node=node.left;
				}else{
					node=stack.pop();
					System.out.println(node.value);
					node=node.right;
				}
			}
		}
  • 后序遍历
		public void postOrder(Node root){
			if(root==null)
				return;	
			Stack<Node> stack1=new Stack<Node>();//子节点
			Stack<Node> stack2=new Stack<Node>();//根节点
			Node node=root;
			stack1.push(node);
			//将已stack1出栈从左到右加入到Stack2
			while(!stack1.isEmpty()){
				node=stack1.pop();
				stack2.push(node);
				if(node.left!=null){
					stack1.push(node.letf);
				}
				if(node.right!=null){
					stack1.push(node.right);
				}
			}
			while(!stack2.isEmpty()){
				System.out.println(stack2.pop()+"  ");
			}
	 	}

3、其他操作

3.1 求二叉树的深度

	*递归*
		public  int treeDepth(TreeNode root){
			if(root==null){
				return 0;
			}
			int nleft=treeDepth(root.left);
			int nright=treeDepth(root.right);
			return nleft>nright?(nleft+1):(nright+1);
		}
	*非递归*
		public int findDepth(TreeNode root){
				if(root==null){
					return 0;
				}
				TreeNode current=null;
				LinkedList queue=new LinkedList();
				queue.offer(root);
				int cur,last;//保存层的节点数
				int level=0;
				while(!queue.isEmpty()){
					cur=0;
					last=queue.size();
					//cur<last控制每次只如一层节点到队列
					while(cur<last){
						current=queue.poll();
						cur++;
						if(current.left!=null){
							queue.offer(current.left);
						}
						if(current.right!=null){
							queue.offer(current.right);
						}
					}
					level++;
				}
				return level;
			}

3.2 是否为平衡二叉树

从下往上遍历,如果子树是平衡二叉树,则返回子树高度,否则返回-1

public static boolean isBalanceBinary(Node root) {
        if (maxDepth(root) == -1) {
            return Boolean.FALSE;
        }
        return Boolean.TRUE;
    }
    public static int maxDepth(Node node){
        if (node == null){
            return 0;
        }
        int left = maxDepth(node.left);
        int right = maxDepth(node.right);
        if (left == -1 || right == -1 || left-right > 1 || right-left > 1){
            return -1;
        }
        return Math.max(left, right) + 1;
    }

3.3 清除某个子树的所有节点

public void clear(BinaryTreeNode node){
			if(node!=null){
				clear(node.getLeft());
				clear(node.getRight());
				node=null;
			}
		}

3.4 节点总个数

		public int size(BinaryTreeNode node){
			if(node==null){
				return 0;
			}else{
				return 1+size(node.getLeft())+size(node.getRight());
			}
		}

// 或
 public static int numsOfNoChildNode(Node root) {
        if (root == null) {
            return 0;
        }
        if (root.left == null && root.right == null) {
            return 1;
        }
        return numsOfNoChildNode(root.left) + numsOfNoChildNode(root.right);
}

3.5 获取最大值

 public static int getMax(Node node) {
        if (node == null) {
            return -1;
        }
        int left = getMax(node.left);
        int right = getMax(node.right);

        if (left > right) {
            left = right;
        }
        if (left > node.val) {
            left = node.val;
        }
        return left;
    }

3.6 第K层节点数

 public static int numsOfkLevelTreeNode(Node root, int k) {
        if (root == null || k < 1) {
            return 0;
        }
        if (k == 1) {
            return 1;
        }
        int numsLeft = numsOfkLevelTreeNode(root.left, k - 1);
        int numsRight = numsOfkLevelTreeNode(root.right, k - 1);
        return numsLeft + numsRight;
    }

3.7 二叉树的创建

	private static Node create(Integer []array,int index){
	        Node tn = null;
	        if (index<array.length) {
	            Integer value = array[index];
	            if (value == null) {
	                return null;
	            }
	            tn = new Node();
	            tn.data=value;
	            tn.left = create(array, 2*index+1);
	            tn.right = create(array, 2*index+2);
	            return tn;
	        }
	        return tn;
	    }

	// 或
	public static Node createTree(int[] arr, int index) {
	    if (index >= arr.length) {
	    	return null;
	    }
	    Node root = new Node(arr[index]);
	    root.left = createTree(arr, 2 * index + 1);
	    root.right = createTree(arr, 2 * index + 2);
	    return root;
	}

4、二叉树比较

4.1 是否相同

 boolean isSameTreeNode(Node t1, Node t2) {
        if (t1 == null && t2 == null) {
            return true;
        } else if (t1 == null || t2 == null) {
            return false;
        }
        if (t1.val != t2.val) {
            return false;
        }
        boolean left = isSameTreeNode(t1.left, t2.left);
        boolean right = isSameTreeNode(t1.right, t2.right);
        return left && right;
}

4.2 镜像转换

 Node mirrorTreeNode(Node root) {
        if (root == null) {
            return null;
        }
        Node left = mirrorTreeNode(root.left);
        Node right = mirrorTreeNode(root.right);
        root.left = right;
        root.right = left;
        return root;
}

4.3 是否为镜像

boolean isMirror(Node t1, Node t2) {
        if (t1 == null && t2 == null) {
            return true;
        }
        if (t1 == null || t2 == null) {
            return false;
        }
        if (t1.val != t2.val) {
            return false;
        }
        return isMirror(t1.left, t2.right) && isMirror(t1.right, t2.left);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值