有关二叉树的常见算法
来源:互联网 发布: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
- 有关二叉树的常见算法
- 有关二叉树的递归算法
- [常见算法]二叉树
- 二叉树的常见算法1
- 有关树的常见算法汇总【持续更新中】
- 二叉树的有关操作
- 二叉树的有关操作
- 有关二叉树的计算
- 二叉树的有关操作
- 二叉树常见算法总结(一)
- 二叉树-常见简单算法题
- 二叉树笔试面试常见算法题
- 常见二叉树基础算法汇总
- java实现二叉树常见遍历算法
- 二叉树常见算法总结-基本二叉树
- 二叉树的常见遍历
- 二叉树的常见操作
- 有关树二叉树的一些操作
- HTML DOM addEventListener()
- JavaScriptCore
- Android源码分析—带你认识不一样的AsyncTask(串并行)
- php7.0取消mysql拓展,所以使用PDO类
- Websphere 启动 时 遇到 端口检测到冲突
- 有关二叉树的常见算法
- 嵌入式学习-驱动开发-lesson6.2-UART驱动初始化和open流程分析
- JavaScript基础(7) 函数表达式
- poj1035Spell checker(串 暴力~~~)
- 文章标题
- c++ new operator与operator new的区别
- Javase
- java根据GPS经纬度坐标计算两点的距离算法
- python中staticmethod classmethod及普通函数的区别