常用二叉树总结

来源:互联网 发布:见过最漂亮的女生知乎 编辑:程序博客网 时间: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