zoukankan      html  css  js  c++  java
  • 树和二叉树总结

    一、定义

    1. 结点分类:树的结点包含一个数据元素和若干指向其子树的分支
    2. 度:结点拥有的子树数称为结点的度,度为0的结点称为叶子节点,树的结点时各结点度的最大值。
    3. 树的层数(深度):从根开始定义,根为第一层,树种的结点的最大层次称为树的深度或者高度。

    二、树的存储结构

    1. 双亲表示法:在每个结点中,附设一个指示器指示双亲在数组中的位置
    2. 孩子表示法:在每个结点中,附设一个指示器指示孩子数和若干指示器指向孩子结点所在的位置
    3. 孩子兄弟表示法:data-firstchild-rightchild

    三、二叉树的定义

    1. 满二叉树:在一棵二叉树中,所有分支结点都存在左子树和右子树,并且所有的叶子节点都在同一层上。
    2. 完全二叉树:完全二叉树是由满二叉树而引出来的,若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数(即1~h-1层为一个满二叉树),第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

    四、二叉树的性质:

    1. 在二叉树的第I层上至少有2^i-1个结点
    2. 深度为K的二叉树至多有2^k-1个结点
    3. 对任意二叉树T,如果其叶子节点数为n0,度为2的结点数为n2,则n0=n2+1。
    4. 具有N个结点的完全二叉树的深度为|log2N|(|x|表示不大于x的最大整数)+1。
    5. 如果对一颗有N个结点的完全二叉数的结点按层数编号,对任意结点I有:
      1. 如果I等于1,则结点无双亲,如果I大于1,则双亲为|I/2|
      2. 如果2*I>N,则结点I无左孩子,否则其左孩子是结点2I.
      3. 如果2*I+1>N,则结点I无右孩子,否则其右孩子是结点2I+1.

    五、二叉树的遍历

    二叉树的四种遍历方式

    前序遍历
    中序遍历
    后序遍历
    层次遍历

    遍历之前先创建一个二叉树
    首先声明结点类

    public class TreeNode {
        public int data;
        public TreeNode leftChild;
        public TreeNode rightChild;
    
        public TreeNode(int data){
            this.data = data;
        }
    
    }
    

    然后创建一颗二叉树

    /**
         * 构建二叉树
         * @param list   输入序列
         * @return
         */
        public static TreeNode createBinaryTree(LinkedList<Integer> list){
            TreeNode node = null;
            if(list == null || list.isEmpty()){
                return null;
            }
            Integer data = list.removeFirst();
            if(data!=null){
                node = new TreeNode(data);
                node.leftChild = createBinaryTree(list);
                node.rightChild = createBinaryTree(list);
            }
            return node;
        }
    

    前序遍历

    实现代码:

    /**
         * 二叉树前序遍历   根-> 左-> 右
         * @param node    二叉树节点
         */
        public static void preOrderTraveral(TreeNode node){
            if(node == null){
                return;
            }
            System.out.print(node.data+" ");//根节点
            preOrderTraveral(node.leftChild);//左子树
            preOrderTraveral(node.rightChild);//右子树
        }
    

    中序遍历

    代码实现:

    /**
         * 二叉树中序遍历   左-> 根-> 右
         * @param node   二叉树节点
         */
        public static void inOrderTraveral(TreeNode node){
            if(node == null){
                return;
            }
            inOrderTraveral(node.leftChild);
            System.out.print(node.data+" ");
            inOrderTraveral(node.rightChild);
        }
    

    后序遍历

    代码实现:

    /**
         * 二叉树后序遍历   左-> 右-> 根
         * @param node    二叉树节点
         */
        public static void postOrderTraveral(TreeNode node){
            if(node == null){
                return;
            }
            postOrderTraveral(node.leftChild);
            postOrderTraveral(node.rightChild);
            System.out.print(node.data+" ");
        }
    

    层序遍历

    代码实现:

    public static void levelOrder(TreeNode root){
            LinkedList<TreeNode> queue = new LinkedList<>();
            queue.add(root);
            while(!queue.isEmpty()){
                root = queue.pop();
                System.out.print(root.data+" ");
                if(root.leftChild!=null) queue.add(root.leftChild);
                if(root.rightChild!=null) queue.add(root.rightChild);
            }
        }
    

    非递归前序遍历

    1. 首先申请一个新的栈,记为stack;
    2. 声明一个结点treeNode,让其指向node结点;
    3. 如果treeNode的不为空,将treeNode的值打印,并将treeNode入栈,然后让treeNode指向treeNode的左结点,
    4. 重复步骤3,直到treenode为空;
    5. 然后出栈,让treeNode指向treeNode的右孩子
    6. 重复步骤3,直到stack为空.
      代码实现:
    public static void preOrderTraveralWithStack(TreeNode node){
            Stack<TreeNode> stack = new Stack<TreeNode>();
            TreeNode treeNode = node;
            while(treeNode!=null || !stack.isEmpty()){
                //迭代访问节点的左孩子,并入栈
                while(treeNode != null){
                    System.out.print(treeNode.data+" ");
                    stack.push(treeNode);
                    treeNode = treeNode.leftChild;
                }
                //如果节点没有左孩子,则弹出栈顶节点,访问节点右孩子
                if(!stack.isEmpty()){
                    treeNode = stack.pop();
                    treeNode = treeNode.rightChild;
                }
            }
        }
    
  • 相关阅读:
    合并报表优化记录
    如何在后台代码中执行原生sql?
    eclipse从数据库逆向生成Hibernate实体类
    用Eclipse进行远程Debug代码
    hibernate自动生成数据库表
    hibernate自动生成数据库表
    php通过UNIX源码编译安装
    php设置方法
    php其他配制选项
    终于做出了目录认证!
  • 原文地址:https://www.cnblogs.com/charlottepl/p/12542485.html
Copyright © 2011-2022 走看看