常用二叉树总结
来源:互联网 发布:见过最漂亮的女生知乎 编辑:程序博客网 时间:2024/05/21 04:22
一、分类
1、二叉查找树
(1)左子树不为空,并且左子树所有结点的值小于根节点的值
(2)右子树不为空,并且右子树所有节点的值大于根节点的值
(3)左右子树也分别是二叉排序树
(4)没有键值相等的结点
2、平衡二叉树(AVL)
左右两个子树的高度差不超过一,并且左右两个子树也都是平衡二叉树
3、红黑树
(1)每个结点要么是红的要不是黑的
(2)根结点必须是黑的
(3)叶子结点必须是黑的
(4)如果父节点是红点,那么两个子结点是黑的
(5)对应每个结点从该结点到其子孙结点的所有路径包含相同的数目
4、B-树
是一种多路搜索树
(1)拥有至少两个子女
(2)每个非根结点包含的关键字个数j满足 m/2-1 < j < m - 1
(3)除根结点以外的所有结点(不包括叶子结点)的度数正好是关键字总数加1,故内部子树k的个数满足 m/2 <= k <= m
(4)所有叶子结点都位与同一层
5、B+树
是B-树的一种变形
6、字典树
是一种Hash树的变种,典型的应用是用户统计、排序和保存大量字符串,所以经常被搜索引擎用于词频的搜索与文本统计
利用字符串的公共前缀来节约存储空间,最大限度减少无谓的字符串比较,查询效率比Hash表要高
字典树和字典是很相似的,先查找第一个字母是否在字典的第一层,如果没有就是没有找到了
二、函数
如下是二叉树的类结构
class TreeNode{ int val; //左孩子 TreeNode left; //右孩子 TreeNode right;}
1、求二叉树的最大深度
//1、求二叉树的最大深度public static int maxDeep(TreeNode node){if(node == null){//这是截止条件return 0;}int left = maxDeep(node.left);int right = maxDeep(node.right);return Math.max(left, right) + 1;}
2、求二叉树的最小深度
//2、求二叉树的最小深度public static int minDeep(TreeNode node){if(node.left == null && node.right == null){//其实这个截止条件也是可以的,和上的类似return 1;}int left = minDeep(node.left);int right = minDeep(node.right);return Math.min(left, right) + 1;}
3、二叉树的结点个数
//3、求二叉树的结点个数public static int numOfTreeNode(TreeNode node){if(node == null){return 0;}int left = numOfTreeNode(node.left);int right = numOfTreeNode(node.right);return left + right + 1;}
4、二叉树中叶子结点的个数
//4、求二叉树中叶子结点的个数public static int numOfChildNode(TreeNode node){if(node == null){return 0;}if(node.left == null && node.right == null){return 1;}int left = numOfChildNode(node.left);int right = numOfChildNode(node.right);return left + right;}
5、二叉树中k层的结点数
//5、求二叉树第k层的结点数public static int numsOfkLevelTreeNode(TreeNode node, int k){if(node == null || k < 1){return 0;}if(k == 1){return 1;}int left = numsOfkLevelTreeNode(node, k-1);int right = numsOfkLevelTreeNode(node, k-1);return left + right;}
6、判断是否是平衡二叉树
//6、判断二叉树是否是平衡二叉树public static boolean isBalanceTree(TreeNode node){if(maxDeepBlance(node) != -1){return true;}return false;}public static int maxDeepBlance(TreeNode node){if(node == null){return 0;}int left = maxDeepBlance(node.left);int right = maxDeepBlance(node.right);if(left == -1 || right == -1 || Math.abs(left-right) > 1){return -1;}return Math.max(left, right) + 1;}
7、判断是否是完全二叉树
//7、是否是完全二叉树public static boolean isCompleteTree(TreeNode node){//找到一非满结点后flag=1,如果发现一个非满结点,接下来的结点不能有孩子结点了//如果有孩子结点,就说明不是完全二叉树,完全二叉树是从左边依次开始排列的if(node == null){return false;}Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.add(node);boolean result = true;boolean flag = false;while(!queue.isEmpty()){TreeNode current = queue.remove();if(flag){if(current.left != null || current.right != null){//如果该结点有孩子结点,是不对的result = false;break;}}else{if(current.left != null && current.right != null){queue.add(current.left);queue.add(current.right);}else if(current.left != null && current.right == null){queue.add(current.left);flag = true;}else if(current.left == null && current.right != null){result = false;break;}else{flag = true;}}}return result;}
8、两个二叉树是否完全相同
//8、两个二叉树是否完全相同public static boolean isSameTreeNode(TreeNode node1, TreeNode node2){if(node1 == null && node2 == null){return true;}else if(node1 == null || node2 == null){return false;}if(node1.val != node2.val){return false;}boolean left = isSameTreeNode(node1.left, node2.left);boolean right = isSameTreeNode(node1.right, node2.right);return left && right;}
9、两个二叉树是否互为镜像
//9、两个二叉树是否互为镜像public static boolean isMirror(TreeNode node1, TreeNode node2){if(node1 == null && node2 == null){return true;}else if(node1 == null || node2 == null){return false;}if(node1.val != node2.val){return false;}boolean left = isMirror(node1.left, node2.right);boolean right = isMirror(node1.right, node2.left);return left && right;}
10、将二叉树进行反转
//10、翻转二叉树或者叫镜像二叉树public static TreeNode MirrorTree(TreeNode node){if(node == null){return null;}TreeNode left = MirrorTree(node.left);TreeNode right = MirrorTree(node.right);node.left = right;node.right = left;return node;}
11、求两个二叉树的最低公共祖先结点
//11、求两个二叉树的最低公共祖先结点public static TreeNode getLastCommonParent(TreeNode root, TreeNode node1, TreeNode node2){ if (root == node1 || root == node2) { return root; } int min = Math.min(node1.val, node2.val); int max = Math.max(node1.val, node2.val); //如果root结点的值大于最大值,就向左搜索 if (root.val > max) { return getLastCommonParent(root.left, node1, node2); } else if (root.val < min) { //如果最小结点的值小于root结点,就向右搜索 return getLastCommonParent(root.right, node1, node2); } //如果root的值处在这两个中间,就返回 return root; }
当二叉树不是二叉搜素数的时候,按照如下方法进行遍历
public static Node lowestAncestor(Node head, Node o1, Node o2) {if (head == null || head == o1 || head == o2) {return head;}Node left = lowestAncestor(head.left, o1, o2);Node right = lowestAncestor(head.right, o1, o2);if (left != null && right != null) {return head;}return left != null ? left : right;}这是按照后序遍历的方式,如果左右都不为空就放回结果了,如果左右都为空或者有一个不为空就直接返回这个结点
12、二叉树的前序遍历迭代方式
//12、二叉树的前序遍历 public static ArrayList<Integer> preOrder(TreeNode root){ Stack<TreeNode> stack = new Stack<TreeNode>(); ArrayList<Integer> list = new ArrayList<Integer>(); if(root == null){ return null; } stack.push(root); while(!stack.empty()){ TreeNode node = stack.pop(); list.add(node.val); if(root.right!=null){ stack.push(root.right); } if(root.left != null){ stack.push(root.left); } } return list; }
13、二叉树的前序遍历递归方式
//13、二叉树前序遍历的递归方式 public static ArrayList<Integer> preOrderReverse(TreeNode root){ ArrayList<Integer> result = new ArrayList<Integer>(); preOrder2(root,result); return result; } public static void preOrder2(TreeNode root,ArrayList<Integer> result){ if(root == null){ return; } result.add(root.val); preOrder2(root.left,result); preOrder2(root.right,result); }
14、二叉树的中序遍历迭代方式
//14、二叉树中序遍历普通方式 public static ArrayList<Integer> inOrder(TreeNode root){ ArrayList<Integer> list = new ArrayList<Integer>(); Stack<TreeNode> stack = new Stack<TreeNode>(); TreeNode current = root; while(current != null || !stack.empty()){ while(current != null){ stack.add(current); current = current.left; } current = stack.pop(); list.add(current.val); current = current.right; } return list; }
15、二叉树是中序遍历递归方式
//15、二叉树前中遍历的递归方式 public static ArrayList<Integer> inOrderReverse(TreeNode root){ ArrayList<Integer> result = new ArrayList<Integer>(); inOrder2(root,result); return result; } public static void inOrder2(TreeNode root,ArrayList<Integer> result){ if(root == null){ return; } inOrder2(root.left,result); result.add(root.val); inOrder2(root.right,result); }
16、二叉树的后序遍历迭代方式
//16、二叉树后序遍历普通 public static ArrayList<Integer> postOrder(TreeNode root){ ArrayList<Integer> res = new ArrayList<Integer>(); if(root == null){ return null; } Stack<TreeNode> s = new Stack<TreeNode>(); Stack<TreeNode> out = new Stack<TreeNode>(); s.push(root); while(!s.isEmpty()){ TreeNode cur = s.pop(); out.push(cur); //前序的时候这里是先入的右结点,这里变了一下顺序 if (cur.left != null) { s.push(cur.left); } if (cur.right != null) { s.push(cur.right); } } //进行一个逆序就可以了 while(!out.isEmpty()) { res.add(out.pop().val); } return res; }
17、二叉树的后序遍历递归方式
//17、二叉树后序遍历递归 public static ArrayList<Integer> postOrderReverse(TreeNode root){ ArrayList<Integer> result = new ArrayList<Integer>(); postOrder2(root,result); return result; } public static void postOrder2(TreeNode root,ArrayList<Integer> result){ if(root == null){ return; } postOrder2(root.left,result); postOrder2(root.right,result); result.add(root.val); }
18、根据前序和中序来构造二叉树
//18、二叉树前序和中序构造二叉树 public TreeNode buildTreeNode(int[] preorder, int[] inorder){ if(preorder.length != inorder.length){ return null; } return myBuildTree(inorder,0,inorder.length-1,preorder,0,preorder.length-1); } public TreeNode myBuildTree(int[] inorder,int instart,int inend, int[] preorder,int prestart,int preend){ if(instart > inend){ return null; } TreeNode root = new TreeNode(preorder[prestart]); int position = findPosition(inorder,instart,inend,preorder[prestart]); root.left = myBuildTree(inorder,instart,position-1,preorder,prestart+1,prestart+position-instart); root.right = myBuildTree(inorder,position+1,inend,preorder,position-inend+preend+1,preend); return root; } public int findPosition(int[] arr, int start, int end, int key){ int i; for(i = start; i <= end; i++){ if(arr[i] == key){ return i; } } return -1; }
19、二叉搜索树中合适位置插入结点
//19、在二叉树中插入结点 public TreeNode insertNode(TreeNode root,TreeNode node){ //这个树的结构是 左 < 中 < 右 的结构 if(root == node){ return node; } //临时结点 TreeNode tmp = new TreeNode(); tmp = root; TreeNode last = null; //找到合适的位置 while(tmp != null){ last = tmp; if(tmp.val > node.val){ tmp = tmp.left; }else{ tmp = tmp.right; } } //将结点插入到里面 if(last != null){ if(last.val > node.val){ last.left = node; }else{ last.right = node; } } return root; }
20、打印二叉树中路径和等于给定值的所有路径
//20、打印出二叉树中结点值等于和的所有路径 public void findPath(TreeNode root, int i){ if(root == null){ return; } Stack<Integer> stack = new Stack<Integer>(); int currentSum = 0; findPath(root, i, stack, currentSum); } public void findPath(TreeNode root, int i, Stack<Integer> stack,int currentSum){ currentSum = currentSum + root.val; stack.push(root.val); //如果两边都为空就进行判断 if(root.left == null && root.right == null){ if(currentSum == i){ for(int path : stack){ System.out.println(path); } } } //如果左边不为空 if(root.left != null){ findPath(root.left, i, stack, currentSum); } //如果右边不为空 if(root.right != null){ findPath(root.right, i, stack, currentSum); } }
21、二叉树的搜索区间,范围爱k1-k2内的结点
//21、二叉树的搜索区间 public static ArrayList<Integer> result; public static ArrayList<Integer> searchRange(TreeNode root,int k1,int k2){ result = new ArrayList<Integer>(); searchHelper(root,k1,k2); return result; }public static void searchHelper(TreeNode root, int k1, int k2) {if(root == null){return ;}if(root.val > k1){searchHelper(root.left, k1, k2);}if(root.val >= k1 && root.val <= k2){result.add(root.val);}if(root.val < k2){searchHelper(root.right, k1, k2);}}
22、二叉树的层次遍历
//22、二叉树的层次遍历public ArrayList<ArrayList<Integer>> levelOrder(TreeNode root){ArrayList<ArrayList<Integer>> result = new ArrayList<ArrayList<Integer>>();if(root == null){return result;}Queue<TreeNode> queue = new LinkedList<TreeNode>();queue.offer(root);while(!queue.isEmpty()){int size = queue.size();ArrayList<Integer> level = new ArrayList<Integer>();for(int i = 0; i < size; i++){TreeNode current = queue.poll();level.add(current.val);if(current.left != null){queue.offer(current.left);}if(current.right != null){queue.offer(current.right);}}result.add(level);}return result;}
23、二叉树是否为二叉查找树
//23、判读二叉树是否是二叉查找数public int lastVal = Integer.MAX_VALUE;public boolean firstNode = true;public boolean isValidBST(TreeNode root) {if(root == null){return true;}if(!isBalanceTree(root.left)){return false;}if(!firstNode && lastVal >= root.val){return false;}firstNode = false;lastVal = root.val;if(!isBalanceTree(root.right)){return false;}return true;}
尊重作者 尊重原创 参考文章:
http://www.jianshu.com/p/0190985635eb
http://blog.csdn.net/yangcs2009/article/details/40146967
1 0
- 常用二叉树总结
- 【二叉树】常用处理与leetcode相关题目总结
- 二叉树常用操作
- 常用数据结构--二叉树
- 二叉树常用算法
- 二叉树常用操作
- 二叉树<总结一>
- 二叉树<总结二>
- 二叉树的总结
- 二叉树算法总结
- 二叉树总结
- 二叉树题总结
- 二叉树学习总结
- 二叉树<总结一>
- 二叉树<总结二>
- 二叉树总结
- 二叉树性质总结
- 二叉树的总结
- flex
- php实现邮件发送功能.
- MTK 软件设置路径(铃声、开关机动画、壁纸等)
- ffmpeg源码简析(十二)FFMPEG中的主要结构体总结
- ecshop后台的新建分页
- 常用二叉树总结
- 阿里云短信服务_发送手机验证码java
- JRE和JDK的区别
- 第八章 React组件的生命周期
- HDU5242:Game(树上贪心)
- Mac 终端使用VPN (已解决)
- WOW.js+animate 帮助你实现滚动页面动画效果
- Qt学习整理
- wireshark学习笔记(一)