二叉树常见问题

                 1.统计二叉树中的结点数目

                  分析:可以使用递归

                   (1)如果二叉树为空,则有0个结点

                   (2)如果二叉树不为空,那么结点数=左子树节点数+右子树节点数+1

                  代码:

private static int getNum(BNode root)
	{
		if(root == null)
			return 0;
		else
			return getNum(root.lChild)+getNum(root.rChild)+1;
	}

                 2.二叉树高度数目

                  分析:可以使用递归

                   (1)如果二叉树为空,则高度为0

                   (2)如果二叉树不为空,那么高度=左子树高度与右子树高度的大者+1

                  代码:

	private static int getHeight(BNode root)
	{
		if(root == null)
			return 0;
		else
			return Math.max(getHeight(root.lChild),getHeight(root.rChild))+1;
	}

                 3.二叉树先序、中序、后序遍历数目

                  分析:可以使用递归

                   (1)如果二叉树为空,则无操作

                   (2)如果二叉树不为空,那么先访问该结点,然后再先序遍历左子树和右子树

                  代码:

	private static void preTraverse(BNode root)
	{
		if(root == null)
			return;
		else
		{
			System.out.println(root.name);
			preTraverse(root.lChild);
			preTraverse(root.rChild);
		}
	}
                中序、后序类似


                 4.二叉树按层遍历数目

                  分析:即DFS,因为不存在图中的复杂关系,所以可以将visited数组省略,且邻接的只有左子树和右子树两种情况

                  代码:

	private static void layerTraverse(BNode root)
	{
		Queue<BNode> queue = new LinkedList<BNode>();
		queue.offer(root);
		
		while(!queue.isEmpty())
		{
			BNode node = queue.poll();
			System.out.println(node.name);
			
			if(node.lChild != null)
				queue.offer(node.lChild);
			if(node.rChild != null)
				queue.offer(node.rChild);
		}
	}

                 5.二叉树第k层的结点数数目

                  分析:可以设根节点为第k层,逆序依次向下为k-1、k-2...........层,那么逆序第一层即为所求的正序第k层,所以

                   (1)如果二叉树为空或者k<1,则返回0

                   (2)如果二叉树不为空,且k==1,那么这就是所求的第k层,返回1

                   (3)如果二叉树不为空,且k>1,那么说明还在所求第k层上面,返回左子树的第k-1层节点数+右子树的第k-1层节点数

                  代码:

	private static int layerKNum(BNode root, int k)
	{
		if(root==null || k<1)
			return 0;
		
		else if(k==1)
			return 1;
		
		else
			return layerKNum(root.lChild, k-1)+layerKNum(root.rChild, k-1);
	}

                 6.二叉树叶子结点数数目

                  分析:递归解法

                   (1)如果二叉树为空,则返回0

                   (2)如果二叉树不为空,且左子树、右子树全为空,那么这就是叶子节点,返回1

                   (3)如果二叉树不为空,且左子树、右子树不全为空,那么说明不是叶子节点,返回左子树的叶子节点数+右子树的叶子节点数

                  代码:

	private static int getLeafNum(BNode root)
	{
		if(root == null)
			return 0;
		
		if (root.lChild == null && root.rChild == null)
			return 1;
		else
			return getLeafNum(root.lChild) + getLeafNum(root.rChild);
	}

                 7.判断二叉树是否是平衡二叉树数目

                  分析:直接根据定义判断

                   (1)如果二叉树为空,则返回true

                   (2)如果二叉树不为空,左子树、右子树全为平衡二叉树且左右子树的高度差小于等于1,那么这就是平衡二叉树,返回真,其余均为false

                  代码:

	private static boolean isAVL(BNode root)
	{
		if(root == null)
			return true;
		
		int lChildHieght = getHeight(root.lChild);
		int rChildHieght = getHeight(root.rChild);
		int c = Math.abs(lChildHieght-rChildHieght);
		
		if(isAVL(root.lChild) && isAVL(root.rChild) && c<=1)
			return true;
		else
			return false;
	}

	private static int getHeight(BNode root)
	{
		if(root == null)
			return 0;
		else
			return Math.max(getHeight(root.lChild),getHeight(root.rChild))+1;
	}

                 8.求二叉树的镜像数目

                  分析:即将二叉树所有左右子树互换

                   (1)如果二叉树为空,则返回true

                   (2)如果二叉树不为空,先获得左子树、右子树的镜像,然后将左右子树互换

                  代码:

	private static BNode mirror(BNode root)
	{
		if(root == null)
			return null;
		BNode lChild = mirror(root.lChild);
		BNode rChild = mirror(root.rChild);
		
		root.lChild = rChild;
		root.rChild = lChild;
		
		return root;
	}

                 9.二叉树根到任意节点的路径数目

                  分析:使用递归

                   (1)如果二叉树为空,则返回false

                   (2)如果二叉树不为空,且根节点即为查找的节点,那么将该根节点入栈,再返回true,表示找到了该节点

                   (3)如果二叉树不为空,但根节点不是所找节点,那么先在左子树中查找先,再在右子树中查找,如果在左子树或右子树中,那么就将根节点入栈,说明是查找节点的祖先,否则返回false

                  代码:

	private boolean getPath(BNode p, BNode target, Stack<BNode> stack) 
	{
		if(p == null)
			return false;
		
		if(p == target)
		{
			stack.push(p);
			return true;
		}
		
		
		if(getPath(p.lChild, target, stack) || getPath(p.rChild, target, stack))
		{
			stack.push(p);
			return true;
		}
		
		return false;
	}


                 10.二叉树中任意两个节点的最低公共祖先数目

                  分析:使用递归

                   (1)分别获得节点node1和node2的路径path1和path2

                   (2)找出path1,path2中最后一个相同的节点,类似于求两个链表第一个相交的节点,只不过现在是倒序

                  代码:

	private static BNode commonParent(BNode root, BNode node1, BNode node2)
	{
		Stack<BNode> path1 = new Stack<BNode>();
		path(root, node1, path1);
		Stack<BNode> path2 = new Stack<BNode>();
		path(root, node2, path2);
		
		//用来记录父亲节点
		BNode parent = null;
		while(!path1.isEmpty() && !path2.isEmpty())
		{
			BNode cur1 = path1.pop();
			BNode cur2 = path2.pop();
			if(cur1 != cur2)
				break;
			else
				parent = cur1;
		}
		
		return parent;
	}

                 11.二叉树中任意两个节点的最低公共祖先数目

                  分析:使用递归

                   (1)分别获得节点node1和node2的路径path1和path2

                   (2)找出path1,path2中最后一个相同的节点,类似于求两个链表第一个相交的节点,只不过现在是倒序

                  代码:


                 12.二叉排序树中任意两个节点的最低公共祖先数目

                  分析:使用递归

                   (1)从根节点开始遍历

                   (2)如果当前节点大于两个节点,那么两个节点必然在当前节点的左子树上;如果当前节点小于两个节点,那么两个节点必然在当前节点的右子树上;如果当前节点在两个节点之间,那么这个节点就是最低公共祖先

                  代码:

	private static BNode sortLca(BNode root,BNode a,BNode b)
	{
		if(root==null)
			return null;
		else
		{
			if(root.val>a.val && root.val>b.val)
				return sortLca(root.lChild, a, b);
			else if(root.val<a.val && root.val<b.val)
				return sortLca(root.rChild, a, b);
			else 
				return root; 
		}
	}



                 13.判断一棵二叉树是否是另一棵二叉树的子结构数目

                      如:                  

                     分析:先获得A中与B根节点相同的节点,可以使用遍历来查找,如果找不到则说明不是

                      然后使用分治

                   (1)如果B为空,则返回true

                   (2)如果B不为空A为空,则返回false

                   (3)如果A、B不相等,则返回false

                   (3)如果A、B相等,则继续判断左右子树

                  代码:

	private static void findRoot(BNode root,int val,BinaryTree find)
	{
		if(root!=null)
		{
			if(root.val==val)
				find.root = root;
			else
			{
				findRoot(root.lChild, val,find);
				findRoot(root.rChild, val,find);
			}
		}
	}
               由于java中无法传递引用,就只能把节点作为其中的值来传递

	private static boolean isSame(BNode root1, BNode root2)
	{
		if(root2 == null)
			return true;
		
		if(root1==null)
			return false;
		
		if(root1.val != root2.val)
			return false;
		else
				return isSame(root1.lChild, root2.lChild) && isSame(root1.rChild, root2.rChild);
	}








  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值