• 数据结构-树与二叉树


    一、树的定义与性质

    <1>定义
    1. 结点(node):树枝分叉处、树叶、树根
    2. 根结点(root):树根
    3. 叶子结点(leaf):叶子结点
    4. 边(edge):茎干和树枝
    5. 子结点(child)
    6. 子树(subtree)
    <2>性质
    1. 树可以没有结点,把这种情况下称为空树(empty tree)
    2. 树的层次(layer),从根结点开始算起来,即根结点为第一层
    3. 把结点的子树棵树称为结点的度(degree),而树的中结点的最大的度称为树的度(也称为树的宽度)
    4. 对于有n个结点的树的边一定是n-1
    5. 叶子结点被定义为0的结点,因此当树只有一个结点时,根结点也算作叶子结点
    6. 结点的深度(depth)是指从根结点(深度为1),开始自顶向下逐层累加至该结点时的深度值;而高度(height)是指从最底层叶子结点开始自底向上逐层累加,而对于树而言,是选择最大的那个数,同时,深度和高度应该是一样的。
    7. 多棵树结合在一起就是森林(forest)
    <3>二叉树的递归定义
    1. 要么二叉树没有根结点,是一棵空树。
    2. 要么二叉树由根结点、左子树、右子树组成,且左子树和有子树都是二叉树。
    • 区分二叉树和度为2的树
    • 满二叉树:每一层结点个数都达到当层能够达到的最大结点数。
    • 完全二叉树:除了最下面一层之外,其余层的结点个数都达到当层的最大结点数,且最下面一层只从左到右连续存在若干结点,而这些连续结点右边的结点全部不存在。
    • 自己即是自己的祖先结点,也是自己的子孙结点。
    <4>二叉树的存储结构
    //二叉链表
    struct node{
        typename data;
        node* lchild;
        node* rchild;
    };
    
    //如果二叉树在建树前根结点不存在,因此其地址一般设为NULL
    node* root = NULL;
    
    //如果想要新建结点,可以使用一下函数
    node* newNode(int v){
        node* Node = new node;
        Node->data = v;//结点权值
        Node->lchild = Node->rchild = NULL;//初始状态下没有左右孩子
        return Node;//返回新建结点的地址
    }
    
    <5>二叉树结点的查找、修改
    • 查找是指在给定数据域的条件下,在二叉树中找到所有数据域为给定数据域的结点,并将它们的数据域修改为给定的数据域。
    void search(node* root, int x, int newdata){
        if(root == NULL){
            return;//递归边界
        }
        if(root->data == x){
            root->data = newdata;
        }
        search(root->lchild, x, newdata);
        search(root->rchild, x, newdata);
    }
    
    <6>二叉树结点的插入
    • insert函数将在二叉树中插入一个数据域为x的新结点
    • 如何判断是否需要加引用?如果函数中需要新建结点,即对二叉树的结构做出修改,就需要加引用;如果只是修改当前已有结点的内容,或仅仅是遍历树,就不需要加引用。
    • 新建结点之后,务必令新结点的左右指针域为NULL。
    void insert(node* &root, int x){
        if(root == NULL){//递归边界
            root = newNode(x);
            return;
        }
        if(由二叉树的性质,x应该插在左子树){
            insert(root->lchild, x);
        }else{
            insert(root->rchild, x);
        }
    }
    
    <7>二叉树的创建
    node* Create(int data[], int n){
        node* root = NULL;
        for(int i = 0; i < n; i++){
            insert(root, data[i]);
        }
        return root;
    }
    
    <8>完全二叉树的存储结构
    1. 对于完全二叉树当中的任何一个结点,其左孩子的编号一定是2x,而右孩子编号一定是2x+1
    2. 1号位存放的必须是根结点
    3. 该数组中元素存放的顺序恰好为该完全二叉树的层序遍历序列
    4. 判断某个结点是否为叶结点的标志为,该结点(记结点下标为root)的左子结点编号root*2大于结点总个数n
    5. 某个结点是否为空结点的标志为该结点下标root大于结点总个数n
    作者:睿晞
    身处这个阶段的时候,一定要好好珍惜,这是我们唯一能做的,求学,钻研,为人,处事,交友……无一不是如此。
    劝君莫惜金缕衣,劝君惜取少年时。花开堪折直须折,莫待无花空折枝。
    曾有一个业界大牛说过这样一段话,送给大家:   “华人在计算机视觉领域的研究水平越来越高,这是非常振奋人心的事。我们中国错过了工业革命,错过了电气革命,信息革命也只是跟随状态。但人工智能的革命,我们跟世界上的领先国家是并肩往前跑的。能身处这个时代浪潮之中,做一番伟大的事业,经常激动的夜不能寐。”
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.
  • 相关阅读:
    微信开发 之 开启开发模式
    微信公众号开发 之 编辑模式使用
    分析各种Android设备屏幕分辨率与适配
    【面向对象设计模式】 适配器模式 (二)
    重构 之 总结代码的坏味道 Bad Smell (一) 重复代码 过长函数 过大的类 过长参数列 发散式变化 霰弹式修改
    【Android 应用开发】Android资源文件
    java 创建并写入文件
    隐藏 HttpClient 在console的日志
    HOW TO CHANGE THE DEFAULT KEY-VALUE SEPARATOR OF A MAPREDUCE JOB
    java 时间戳转换
  • 原文地址:https://www.cnblogs.com/tsruixi/p/12307459.html
Copyright © 2020-2023  润新知