个人学习-STL:Set前置-tree

参考资料:

[1]程杰.大话数据结构[M].

[2][美]Robert Sedgewic,Jevin Wayne. 算法Algorithms[M].谢路云译

1.基本脉络:

树实际是链表的衍生结构,从链表到二叉树,到二叉搜索树,到平衡二叉树(AVL),进行一个总结;

2.树的一些基本概念:

1)树实际是n个节点的有限集。n = 0 时称为空树;任何一个非空树,有且仅有一个根节点(root); n > 0 时,其余节点又可分为m个 _不相交_的有限集,每个集合都可看作一个树,即根的子树(subtree)
2)节点所拥有的子树称为子树的度(Degree)。度为0的节点称为叶节点(leaf)或者终端节点;
3)节点衍生出子树的根节点,称为子节点(child),同一根节点下子树节点为兄弟节点(slibing);

3.二叉树:

3.1二叉树的基本构造:

二叉树是最多存在两个子树的树形结构,每个节点单独看都是一个二叉树;
几种特殊的二叉树:
1)斜树:仅有左子树或者右子树的二叉树,实际就是一个线性表;
2)满二叉树:所有节点的度都是2,且所有的叶子节点都在一层上,称为满树
3)完全二叉树:概念定义比较难理解的一种二叉树,简单这样理解[1,2,3,4,5,6,7,8];这样的序列容器,把它以层序优先进行二叉树,它就可以构成一个完全二叉树,类似于广度优先的遍历;(详情见按层遍历二叉树)

个人学习-STL:Set前置-tree
3.2 简单二叉树的存储:
  typedef struct BinTree
  {
      int element;
      struct BinTree * ltree;
      struct BinTree * rtree;
  };
3.3二叉树构造和遍历:
前序,中序,后序

实际就是节点,左子叶,右子树之间的顺序;
前序:
若二叉树为空,则空操作返回,否则先访问节点,再先序访问左树,结束后先序访问右树;上图的先序结果为1,2,4,8,9,5,10,3,6,7;(节点在左右子树前被访问)
先遍历节点,再遍历左子树,再遍历右子树

  void pre_search_BinTree(struct BinTree * tree)
  {
      if (tree == NULL)
      {
          return;
      }
      preintf("%d", tree ->element);
      pre_search_BinTree(tree -> ltree);
      pre_search_BinTree(tree -> rtree);

  }

中序:
若二叉树为空,则空操作返回,否则先中序遍历左树,再访问元素,再中序遍历右树

  void on_search_BinTree(struct BinTree * tree)
  {
      if (tree == NULL)
      {
          return;
      }
      pre_search_BinTree(tree -> ltree);
      preintf("%d", tree ->element);
      pre_search_BinTree(tree -> rtree);
  }

后序:
二叉树为空,则空操作返回,否则先后序遍历左树,再后序遍历右树,再访问元素;

void pos_search_BinTree(struct BinTree * tree)
{
    if (tree == NULL)
    {
        return;
    }
    pre_search_BinTree(tree -> ltree);
    pre_search_BinTree(tree -> rtree);
    preintf("%d", tree ->element);
}
深度遍历和广度遍历(层序遍历)

深度遍历-先序:先序遍历的非递归版,实际就是一个简单的深度遍历,以访问最深的路径为目的;(在图的部分会被广泛使用)

  // 直接用了STL里的stcak,note:设计上把弹出栈顶元素拆成里top()和pop()两个函数,具体原因需要研究一下
void DFS(struct BinTree* tree)
{
    // 节点栈,利用先进后出的特性来处理
    if(tree == nullptr)
        return;
    stack<bintree*> node_stack;
    // &#x6839;&#x8282;&#x70B9;&#x5165;&#x6808;
    node_stack.push(tree);
    while (!node_stack.empty())
    {
        // &#x8BBF;&#x95EE;&#x5143;&#x7D20;;
        BinTree* top_elem = node_stack.top();
        node_stack.pop(); // &#x79FB;&#x9664;;
        // &#x5148;&#x8FDB;&#x540E;&#x51FA;&#xFF0C;&#x60F3;&#x5148;&#x8BBF;&#x95EE;&#x5DE6;&#x5B50;&#x6811;&#x7684;&#x8BDD;&#xFF0C;&#x53F3;&#x8FB9;&#x5148;&#x5165;&#x6808;
        if(top_elem ->rtree)
        {
            node_stack.push(top_elem -> rtree);
        }
        if(top_elem -> ltree)
        {
            node_stack.push(top_elem -> ltree);
        }
        // &#x9700;&#x8981;delete&#x4E00;&#x4E0B;&#xFF0C;&#x53EF;&#x80FD;&#x4F1A;&#x5185;&#x5B58;&#x6CC4;&#x6F0F;-->&#x5F85;&#x9A8C;&#x8BC1;;
        delete top_elem;
    }
</bintree*>

广度优先遍历(BFS):
按照每一层的顺序对二叉树进行遍历,root->层1 -> 层2 -> 层3 ;如上文,如果把一个容器里的数据,按层序展开,得到的就是一个完全二叉树

  /* &#x961F;&#x5217;&#x5B9E;&#x73B0;&#xFF0C;&#x5148;&#x8FDB;&#x5148;&#x51FA;;
    tree-    A
           /   \
          B     C
         / \   / \
        D   E  F  G
      queue: 1. push(A)     A
             2. front_pop:A&#xFF0C; pushback:BC    BC
             3. front_pop:B,  pushback:DE    CDE
             4. front_pop:C,  pushback:GF    DE
             5. frint_pop .....

*/
  void BFS(struct BinTree * tree)
{
    if(tree == nullptr)
    {
        return;
    }
    queue<bintree *> node_queue;
    // &#x6839;&#x8282;&#x70B9;&#x5165;&#x961F;&#x5217;;
    node_queue.push(tree);
    while (!node_queue.empty())
    {
        BinTree * node = node_queue.front();
        node_queue.pop(); // &#x5C3E;&#x8FDB;&#x5934;&#x51FA;FIFO;
        if(node -> ltree)
        {
            node_queue.push(node ->ltree);
        }
        if(node -> rtree)
        {
            node_queue.push(node -> rtree);
        }
    }
}
</bintree>
3.4基础二叉树的缺点:

1.当节点n的数量比较多的时候,子叶上会有大量空指针;
2.找不到前驱点,需要找到某个节点元素的前驱点,需要再去遍历;
由于这两个缺点,需要把原始二叉树进行改进,引出了线索二叉树;

4.线索二叉树:

鉴于上述的两个原因,在结构设计上,添加进了一个思路:
将节点中的空指针,指向本节点的前驱点和后继点,就可以实现二叉树的线索化,把此时如果只考虑前驱和后继,不考虑节点间的亲缘关系的话,此时数据类型就是一个双向链表。
常用的线索化思路:中序遍历,将空的rtree ptr指向后继点,ltree ptr指向前驱点;(枚举后较为便捷的做法其他case更为复杂);
此时,节点需要两个标识位,来分辨指针表示的是实际的子树,还是前驱后继关系;

typedef char TelemType;
typedef enum{Link, Thread} PointerFlag;
typedef struct BiThrNode
{
    TelemType elem;
    struct BiThrNode * ltree;
    struct BiThrNode * rtree;
    PointerFlag lflag;
    PointerFlag rflag;
};

// &#x904D;&#x5386;&#x7EBF;&#x7D22;&#x5316;
// &#x9700;&#x8981;&#x4E00;&#x4E2A;&#x91CF;&#xFF0C;&#x5B9A;&#x4E49;&#x524D;&#x4E00;&#x4E2A;&#x8BBF;&#x95EE;&#x7684;&#x8282;&#x70B9;;
BiThrNode* pre;
void InThreading(struct BiThrNode * tree)
{
    if (tree == NULL)
    {
        return;
    }
    InThreading(tree -> ltree);
    if(!tree ->ltree)
    {
        tree -> lflag = Thread;
        tree -> ltree = pre;

    }
    if(!pre -> rtree)
    {
        pre ->rflag = Thread;
        pre ->rtree = tree;
    }
    pre = tree;
    InThreading(tree -> rtree);
}

Original: https://www.cnblogs.com/Albert-lihai/p/16579215.html
Author: Albert_禄遥
Title: 个人学习-STL:Set前置-tree

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/644093/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 问题开发

    1.路由协议 2.snmpv2 v3 发展异同 ?原因 解决什么问题 Original: https://www.cnblogs.com/hshy/p/16539009.htmlA…

    技术杂谈 2023年5月31日
    0120
  • DP 优化小技巧

    收录一些比较冷门的 DP 优化方法。 树上依赖性背包形如在树上选出若干个物品做背包问题,满足这些物品连通。由于 01 背包,多重背包和完全背包均可以在 (\mathcal{O}(V…

    技术杂谈 2023年6月21日
    0128
  • 【证券从业】金融基础知识-第六章 证券投资基金01

    注1:后续学习并整理到第八章,全书完结后再合并成一个笔记进行源文件分享 注2:本章内容巨多,大约分为三篇文章记录消化 posted @2022-06-10 16:38 陈景中 阅读…

    技术杂谈 2023年7月10日
    074
  • 谈谈Raft

    本文主要参考: 极客时间-etcd 实战课 GitChat-分布式锁的最佳实践之:基于 Etcd 的分布式锁 谈到分布式协调组件,我们第一个想到的应该是大名鼎鼎的Zookeeper…

    技术杂谈 2023年7月25日
    082
  • 每天一个 HTTP 状态码 205

    205 Reset Content 表示服务器成功地处理了客户端的请求,要求客户端… 205 Reset Content 205 Reset Content 表示服务器…

    技术杂谈 2023年7月11日
    065
  • argo-cd基于Kubernetes的声明式持续部署

    argo-cd基于Kubernetes的声明式持续部署 什么是argo-cd? Argo CD是一个基于Kubernetes的声明式GitOps持续交付工具。 为什么CD ? 应用…

    技术杂谈 2023年5月31日
    064
  • HTML:2.基本结构

    HTML初识 HTML(Hyper Text Markup Language):超文本标记语言 所谓超文本,有2层含义: 它可以加入图片、声音、动画、多媒体等内容(超越文本限制 )…

    技术杂谈 2023年7月11日
    083
  • Docker常用命令

    配置相关 docker version 查看版本 docker ps 查看当前运行的container docker exec -it php-fpm bash 进入cantain…

    技术杂谈 2023年7月10日
    093
  • Spring框架中bean的生命周期

    Spring对bean进行实例化; Spring将值和bean的引用注入到bean对应的属性中; 如果bean实现了BeanNameAware接口,Spring将bean的ID传递…

    技术杂谈 2023年7月24日
    069
  • tcpdump交叉编译及使用

    第一步.下载官方网站:http://www.tcpdump.org/需要下载libpcap包和tcpdump包我下载的版本是:libpcap-1.4.0.tar.gz和tcpdum…

    技术杂谈 2023年6月1日
    0113
  • pycharm alt+f7(查找)显示动态用法的结果过多(dynamic usages)

    在脚本语言中查找引用时,如果有同名函数,在动态用法那一栏会出现大量的结果,,如何缩小或者动态用法(dynamic usages)的结果呢? 在官网上也有提出了这个问题,但官方没有给…

    技术杂谈 2023年6月1日
    0107
  • get,post,put,delete四种基础方法对应增删改查

    PUT,DELETE,POST,GET四种基础方法对应增删改查 1、 GET请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的 select操作一样,只是用来 查询…

    技术杂谈 2023年7月11日
    066
  • 【7】2022年9-10月

    9月23日-10月28日 从7月份以来右手臂频繁酸痛无力,一开始没重视以为是软组织的损伤导致的,所以只贴敷膏药进行缓解,9月以来,右手臂肿痛明显,开始出现变形,我意识到可能不是软组…

    技术杂谈 2023年7月10日
    069
  • PyQt5 设置鼠标形状

    ################################ PyQt5中文网 – PyQt5全套视频教程 # https://www.PyQt5.cn/ # 主讲: 村长 #…

    技术杂谈 2023年5月31日
    093
  • win10下计算文件哈希值的方法

    cmd下使用certutil命令 使用方法: certutil -hashfile FILE_NAME ALGORITHM_NAME 支持的加密算法包括:MD2,MD4,MD5,S…

    技术杂谈 2023年7月25日
    070
  • Python学生信息管理系统(精简版)

    代码: #&#x5B58;&#x653E;&#x5B66;&#x751F;&#x4FE1;&#x606F; student = li…

    技术杂谈 2023年6月21日
    095
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球