数据结构之二叉树——相关问题总结

来源:互联网 发布:栅格数据 查找工具 编辑:程序博客网 时间:2024/05/17 07:48

最近发现二叉树貌似很受面试官青睐,明天要参加某大型互联网公司二面,来总结总结热热身的说。二叉树顾名思义每个节点最多有两个孩子节点,由于二叉树的建立本身就是一个递归的过程,所以很多二叉树相关问题都可以使用递归的方法进行求解,但是也有很多面试官喜欢问×××的非递归实现。下面对一些常见的二叉树问题进行总结,原帖使用C,本小博用Java改写了一下。原文地址:http://blog.csdn.net/luckyxiaoqiang/article/details/7518888。

建立自己的二叉树结构

class BinaryTree {int data;BinaryTree left;BinaryTree right;public BinaryTree(int data) {this.data = data;}}
、求二叉树节点个数

        //二叉树节点的个数(递归)//(1)如果二叉树为空,节点个数为0//(2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1int GetNodeNum(BinaryTree root) {if(root == null) {return 0;}return GetNodeNum(root.left) + GetNodeNum(root.right) + 1;}
二、求二叉树深度

        //二叉树深度(递归)//(1)如果二叉树为空,二叉树的深度为0//(2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1int GetDepth(BinaryTree root) {if(root == null) {return 0;}return Math.max(GetDepth(root.left), GetDepth(root.right)) + 1;}
三、前、中、后续遍历

这里只给出前序遍历,后两者同理

        //前序遍历递归解法://(1)如果二叉树为空,空操作//(2)如果二叉树不为空,访问根节点,前序遍历左子树,前序遍历右子树void PreOrderTraverse(BinaryTree root) {if(root != null) {System.out.print(root.data + " ");PreOrderTraverse(root.left);PreOrderTraverse(root.right);}}
、分层遍历

        //相当于广度优先搜索,使用队列实现。队列初始化,将根节点压入队列。当队列不为空,进行如下操作:弹出一个节点,访问,//若左子节点或右子节点不为空,将其压入队列。//java的队列没搞定,那就用ArrayList吧void LevelTraverse(BinaryTree root) {if(root != null) {ArrayList<BinaryTree> l = new ArrayList<BinaryTree>();l.add(root);int cur = 0;int last = 1;while(cur < last) {System.out.print(l.get(cur).data + " ");if(l.get(cur).left != null) {l.add(l.get(cur).left);}if(l.get(cur).right != null) {l.add(l.get(cur).right);}last = l.size();cur++;}}}
五、求二叉树第k层的节点个数

        int GetNodeNumKthLevel(BinaryTree root, int k) {if(root == null || k == 0) {return 0;}if(k == 1) {return 1;}return GetNodeNumKthLevel(root.left,k-1) + GetNodeNumKthLevel(root.right,k-1);}
六、求二叉树中叶子节点的个数

        //递归解法://(1)如果二叉树为空,返回0//(2)如果二叉树不为空且左右子树为空,返回1//(3)如果二叉树不为空,且左右子树不同时为空,返回左子树中叶子节点个数加上右子树中叶子节点个数int GetLeafNodeNum(BinaryTree root) {if(root == null) {return 0;}else if(root.left == null && root.right == null) {return 1;}else {return GetLeafNodeNum(root.left) + GetLeafNodeNum(root.right);}}
七、判断两棵二叉树是否结构相同

        //不考虑数据内容。结构相同意味着对应的左子树和对应的右子树都结构相同。//递归解法://(1)如果两棵二叉树都为空,返回真//(2)如果两棵二叉树一棵为空,另一棵不为空,返回假//(3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假boolean StructureCmp(BinaryTree r1,BinaryTree r2) {if(r1 == null && r2 == null)return true;else if(r1 == null && r2 != null)return false;else if(r1 != null && r2 == null)return false;else {if(StructureCmp(r1.left,r2.left) && StructureCmp(r1.right,r2.right))return true;elsereturn false;}}
八、求二叉树的镜像
        //递归解法://(1)如果二叉树为空,返回空//(2)如果二叉树不为空,求左子树和右子树的镜像,然后交换左子树和右子树BinaryTree Mirror(BinaryTree root) {if(root == null) {return root;}BinaryTree left = Mirror(root.left);BinaryTree right = Mirror(root.right);root.left = right;root.right = left;return root;}
九、求二叉树中两个节点的最低公共祖先节点

        //递归解法://(1)如果两个节点分别在根节点的左子树和右子树,则返回根节点//(2)如果两个节点都在左子树,则递归处理左子树;如果两个节点都在右子树,则递归处理右子树//非递归解法://先求从根节点到两个节点的路径,然后再比较对应路径的节点就行,最后一个相同的节点也就是他们在二叉树中的最低公共祖先节点boolean FindNode(BinaryTree root,BinaryTree node) { //此函数用于查看节点是否在子树上if(root == null || node == null) {return false;}if(node == root) {return true;}boolean found = FindNode(root.left,node);if(!found) {found = FindNode(root.right,node);}return found;}BinaryTree GetLastCommonParent(BinaryTree root,BinaryTree r1,BinaryTree r2) {if(root == null) {return root;}if(FindNode(root.left,r1)) {if(FindNode(root.right,r2)) {return root;}else {return GetLastCommonParent(root.left,r1,r2);}}else {if(FindNode(root.right,r2)) {return root;}else {return GetLastCommonParent(root.right,r1,r2);}}}
十、求二叉树中节点的最大距离

        //即二叉树中相距最远的两个节点之间的距离。//递归解法://(1)如果二叉树为空,返回0,同时记录左子树和右子树的深度,都为0//(2)如果二叉树不为空,最大距离要么是左子树中的最大距离,要么是右子树中的最大距离,//   要么是左子树节点中到根节点的最大距离+右子树节点中到根节点的最大距离,同时记录左子树和右子树节点中到根节点的最大距离。int GetMaxDistance(BinaryTree root) {if(root == null) {return 0;}int left = root.GetDepth(root.left);int right = root.GetDepth(root.right);int res = left + right;res = Math.max(res, GetMaxDistance(root.left));res = Math.max(res, GetMaxDistance(root.right));return res;}

0 0
原创粉丝点击