有关二叉树的常见算法

来源:互联网 发布:java json格式化输出 编辑:程序博客网 时间:2024/05/21 09:34

最近在刷算法题,抽空把二叉树的一些最基本算法进行总结。所有函数都基于以下树的定义:

//数据结构定义public class TreeNode {      int val;      TreeNode left;      TreeNode right;      TreeNode(int x) { val = x; } }


1. 二叉树的三种遍历方式:前序,中序,后序。

先序是先遍历根,再遍历左子树,再遍历右子树;

中序是先遍历左子树,再遍历根,再遍历右子树;

后序是先遍历右子树,再遍历根,再遍历左子树;


//先序遍历算法public static void preOrderTraverse(TreeNode root){  if(root == null) return;  preOrderTraverse(root.left); System.out.println(root.val); preOrderTraverse(root.right); }//中序遍历算法public static void preOrderTraverse(TreeNode root){  if(root == null) return; <span style="white-space:pre"></span>System.out.println(root.val);
<span style="white-space:pre"></span>preOrderTraverse(root.left); 
<span style="white-space:pre"></span>preOrderTraverse(root.right); 
}


//后序遍历算法public static void preOrderTraverse(TreeNode root){  if(root == null) return;  preOrderTraverse(root.left);                  preOrderTraverse(root.right);                  System.out.println(root.val);
}

2.  找出根节点到每个叶子节点的路径。

       public static void PrintList(ArrayList<TreeNode> list){ for(int i=0;i<list.size();i++)System.out.print(list.get(i).val+"   "); System.out.println(); } public static boolean isParent(TreeNode parent,TreeNode child){  //判断是否为父子关系  if(parent == null || child == null) return false; if(child == parent.left || child == parent.right) return true;  return false; }  public static void getPath(TreeNode root) {         if(root == null) return;  Stack<TreeNode> stack = new Stack<TreeNode>();    ArrayList<TreeNode> list = new ArrayList<TreeNode>();  //存储路径 stack.push(root);  while(!stack.isEmpty()){  TreeNode temp = stack.pop(); list.add(temp);  if(temp.right != null) stack.push(temp.right); if(temp.left != null) stack.push(temp.left);if (temp.left == null & temp.right == null) { //如果是叶子节点输入路径PrintList(list);while ((!stack.isEmpty()) && (!list.isEmpty()) && (!isParent(list.get(list.size() - 1), stack.peek())))list.remove(list.size() - 1);} }  }

3. 求树的深度

   int maxDepth(TreeNode* root) {        int deep = 0;        if(root == NULL)            return 0;        if(root->left == NULL && root->right == NULL)            return 1;        if(root)        {            int ldeep = maxDepth(root->left);            int rdeep = maxDepth(root->right);            deep = (ldeep > rdeep ? ldeep:rdeep ) + 1;            }                return deep;    }

4. 将二叉树反转,每一层的左右子树交换。

       TreeNode* invertTree(TreeNode* root) {                if(root == NULL)            return root;        else        {            TreeNode *temp = root->left;            root->left = invertTree(root->right);            root->right = invertTree(temp);                    }        return root;    }

5. 判断两颗二叉树是否相等,即结构相等,数值相等。

    bool isSameTree(TreeNode* p, TreeNode* q) {                if(p==NULL && q == NULL)            return 1;        if(p==NULL || q == NULL)            return 0;                    if(p->val == q->val)   //P树的左、右子树和Q的左、右子树分别相等         return isSameTree(p->left,q->left) && isSameTree(p->right,q->right);        else         return 0;            }

6. 二叉搜索树的最近公共父节点。

     public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {                if(root== null || p==null ||q==null) return null;       //如果一个比根节点大,一个比根节点小,则直接返回根节点</span>         if((p.val<= root.val && q.val>=root.val) || (p.val>=root.val && q.val<=root.val)){ return root; }   //如果都比根节点小,则将根节点的左孩子作为新的根节点</span> else if(p.val< root.val && q.val<root.val){ return lowestCommonAncestor(root.left,p,q); }    //如果都比根节点大,则将根节点的右孩子作为新的根节点 else{ return lowestCommonAncestor(root.right,p,q); }     }

7. 二叉树是否高度平衡,即左子树和右子树的高度差距不大于1.

        public int getDepth(TreeNode root){if(root == null) return 0;int ld = getDepth(root.left);int rd = getDepth(root.right);return 1 + Math.max(ld, rd);}public boolean isBalanced(TreeNode root) {    if(root == null) return true;    if(root.left == null && root.right == null) return true;        if(Math.abs(getDepth(root.left) - getDepth(root.right)) > 1)        return false;   //左子树和右子树高度相差不超过1           return isBalanced(root.left) & isBalanced(root.right);            }
8.判断一个二叉树是否对称,即左右子树以根节点为对称轴。

      public boolean isRight(TreeNode left,TreeNode right){if(left == null && right == null) return true;if((left == null && right != null) || (left != null && right == null)) return false;if(left.val != right.val)return false;else    //左子树的左孩子和右子树的右孩子相等,左子树的右孩子和右子树的左孩子相等<span style="white-space:pre"></span>return isRight(left.left,right.right) && isRight(left.right,right.left);}public boolean isSymmetric(TreeNode root) {if(root == null) return true;return isRight(root.left,root.right);}
9. 树按层次遍历,放入一个List<List<Integer>>中,即每个小list中放树的一层的数值。

      public static void getList(TreeNode root, List<List<Integer>> list,int height){if(root == null) return;if(height >= list.size())list.add(new ArrayList<Integer>());list.get(height).add(root.val);   //假设提前知道该节点在那一层,直接加入到List中,非常巧的思路</span>getList(root.left, list,height+1);getList(root.right, list,height+1);}public static List<List<Integer>> levelOrder(TreeNode root) {List<List<Integer>> list = new ArrayList<List<Integer>>();getList(root,list,0);return list;}

本人认为树的很多算法都可以巧妙的用递归实现,先把基本的算法都练熟了,经常温故,遇到新的题目时,都是基础题的变形,以不变应万变。奋斗


1 0
原创粉丝点击