二叉树常见问题

来源:互联网 发布:淘宝卖鲜花资质 编辑:程序博客网 时间:2024/06/06 03:32

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

                  分析:可以使用递归

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

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

                  代码:

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

                 2.二叉树高度数目

                  分析:可以使用递归

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

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

                  代码:

private static int getHeight(BNode root){if(root == null)return 0;elsereturn 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;elsereturn 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;elsereturn 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;elsereturn false;}

private static int getHeight(BNode root){if(root == null)return 0;elsereturn 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;elseparent = 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;elsereturn isSame(root1.lChild, root2.lChild) && isSame(root1.rChild, root2.rChild);}








0 0
原创粉丝点击