树的存储结构

  • 一、双亲表示法
  • 二、孩子表示法(孩子链表)
  • 三、孩子兄弟表示法(二叉树表示法、二叉链表表示法)
  • 四、森林(树)和二叉树的转换

一、双亲表示法

实现:定义数组结构存放树的结点,每个结点含两个域:
数据域:存放结点本身数据信息。
双亲域:指示本结点的双亲结点在数组中的位置。

结点结构表示为:

data parent

data是数据域,parent是指针域
例如:

可表示为:

r=0,n=10.(根结点位置和结点个数)

这样的存储结构,根据结点parent指针很容易找到它的双亲结点,所用时间复杂度为O(1),直到parent为-1时,找到了树的根结点,但是我们要知道结点的孩子是什么,对不起,请遍历整个结构才行。

所以双亲表示法特点是:找双亲容易,找孩子难。

结点结构:

typedef struct PTNode{int data;int parent;//双亲位置域
}PTNode;

树结构定义:

#define MAX_TREE_SIZE 100
typedef struct{PTNode nodes[MAX_TREE_SIZE];int r,n;//根结点的位置和结点个数
}PTree;

我们可以把结点扩展来解决找孩子结点的问题,但存储结构的设计是一个非常灵活的过程。一个存储结构设计的是否合理,取决于基于该存储结构的运算是否适合、是否方便,时间复杂度好不好等等。

二、孩子表示法(孩子链表)

具体办法是:把每个结点的孩子结点排列起来,看成是一个线性表,以单链表作存储结构,则n个结点有n个孩子链表(叶子结点的孩子链表为空),然后n个头指针又组成一个线性表,采用顺序存储结构,存放进一个一维数组中,如图所示

为此,设计两种结点结构,一个是孩子链表的孩子结点:

child next

child是数据域,用来存储某个结点在表头数组中的下标,next为指针域,存储指向某结点的下一个孩子结点的指针。

另一个是表头数组的表头结点,也就是双亲结点:

data first child

其中,data是数据域,firstchild是头指针域,存储该结点的孩子链表的头指针。

孩子表示法的结构定义代码:

孩子结点结构


typedef struct CTNode{//孩子结点int child;struct CTNode *next;
}*ChildPtr;

表头结构(双亲结构)

typedef struct       //表头结构
{       int data;ChildPtr firstchild;
}CTBox;//孩子链表

树结构:

#define MAX_TREE_SIZE 100
typedef syruct      //树结构
{CTBox nodes[MAX_TREE_SIZE];//结点数组int n,r;//结点数和根结点的位置
}CTree;

特点:找孩子易,找双亲难

这样的结构对于我们要查找某个结点的某个孩子,或者找某个结点的兄弟,只需要查找这个结点的孩子单链表即可。对于遍历整棵树也是很方便的,对头结点的数组循环即可。


但是,要找双亲结点却很麻烦,我们可以把双亲表示法和孩子表示法综合一下,称为双亲孩子表示法,算是孩子表示法的改进。

我们在表头结构中新增加一个成员即可,存储双亲下标。为了多存储双亲,操作方便,我们牺牲了空间。

三、孩子兄弟表示法(二叉树表示法、二叉链表表示法)

任意一棵树,它的结点的第一个孩子如果存在就是唯一的,它的右兄弟如果存在也是唯一的。因此,我们用二叉链表作树的存储结构,链表中每个结点的两个指针域分别指向第一个孩子结点和此结点的下一个兄弟结点
,根结点没有兄弟,置为空。
结点结构如表:


画的有些丑,将就着看哈~(最右边是nextsibling,写错了)

//树的孩子兄弟表示法结构定义
typedef struct CSNode
{int data;struct CSNode *firstchild,*nextsibling;
}CSNode,*CSTree;//结点类型和指向结点类型的指针,指针表示孩子兄弟表示的二叉链表结构

举例:

这种表示法,给查找某个结点的某个孩子带来方便,当然想找到结点的双亲,这个表示法也是有缺陷的,所以真的有必要的话,完全可以再增加一个parent指针域来解决快速查找双亲的问题,大家试试吧

此表示法的最大好处就是把一棵复杂度的树变成了一颗二叉树。


四、森林(树)和二叉树的转换

1)将树转化为二叉树进行处理,利用二叉树的算法来实现对树的操作
2)由于树和二叉树都可以用二叉链表作存储结构,则以二叉链表作媒介可以导出树与二叉树之间的一个对应关系。

  1. 将森林转换成二叉树
    1)加线:在兄弟之间加一连线
    2)抹线:对每个结点,除了其左孩子外,去除其与其余孩子之间的关系
    3)旋转:以树的根结点为轴心,将整数顺时针转45度。
    记忆口诀:兄弟相连留长子
    过程如下:加线->抹线->旋转

  2. 将二叉树转换为森林
    步骤:
    1)加线:若p结点是双亲结点的左孩子,则将p的右孩子,右孩子的右孩子… …沿着分支找到所有的右孩子,都与p的双亲用线连起来
    2)抹线:抹掉原二叉树中双亲与右孩子之间的连线
    3)调整:将结点按层次排列,形成树结构

记忆口诀:左孩右右连双线,去掉原来右孩线
过程如下:加线->抹线->调整(旋转)


内容参考:
《数据结构》严蔚敏

双亲表示法、孩子表示法、孩子兄弟表示法(二叉树表示法),森林和二叉树的转换相关推荐

  1. 多叉树的二叉树表示法(左儿子右兄弟)

    在二叉树的基础上,我们可以扩展出任意多个叉的树.即,多叉树.然而,此时又面临着另外一个问题: 当孩子结点无限制时,我们并不知道预先要分配多少个属性,且当仅有少数元素拥有多个子节点时,将会造成大量的空间 ...

  2. 树和森林转二叉树,二叉树无右孩子(或右指针域为空)的结点个数计算思路

    前提是知道非终端结点(分支结点)的个数,假设非终端结点的个数为n 1.对于树转二叉树: 因为转化规则是"左孩子右兄弟",如果有n个分支结点,因为每个分支结点都会有孩子,这些孩子都是 ...

  3. 学计算机的男孩子怎么追女孩子,男孩子追女孩子的套路,原来有这么多,快来学一学...

    导语 你有没有喜欢的女孩子呢?那有没有跟她表白呢?或者有没有追到手呢?俗话说没吃过猪蹄也见过猪跑啊,追女孩子的套路虽然许多人在用,可是层出不穷的追女孩套路,你真的都了解吗?我们都知道女孩子喜欢男孩子是 ...

  4. 森林转二叉树,二叉树无右孩子结点的个数

    对于森林中的所有分支结点(分支结点就是非叶子结点,包含了根节点):其所有孩子都会连到它对应二叉树的左子树中,最左边的孩子成为这棵左子树的根节点,最右边的孩子由于没有兄弟了,转为二叉树后,它的右孩子一定 ...

  5. c语言编程代码对父母感恩,c语言中编程:每个做父母的都关心自己孩子成人后孩子的生高:...

    c语言中编程:每个做父母的都关心自己孩子成人后孩子的生高: 据有关生理卫生知识与数理统计分析表明,影响小孩成人后的身高的因素包括遗传.饮食习惯与体育锻炼等.小孩成人后的身高与其父母的身高和自身的性别密 ...

  6. 二叉树经典题之根据二叉树创建字符串(二叉树的括号表示法)

    前言: 二叉树刷题是有固定思维的,请移步 README]二叉树刷题框架 根据二叉树创建字符串 题目 点击跳转:LeetCode 递归解法 这道题其实考察到的是二叉树的括号表示法,括号表示法依靠括号的划 ...

  7. csv 中 数值被自动转换成科学计数法 的问题 excel打开后数字用科学计数法显示且低位变0的解决方法

    csv 中 数值被自动转换成科学计数法 的问题 excel打开后数字用科学计数法显示且低位变0的解决方法 参考文章: (1)csv 中 数值被自动转换成科学计数法 的问题 excel打开后数字用科学计 ...

  8. 容量法和库仑法的异同点_库伦法水分仪和容量法的区别与差异

    库伦法水分仪和容量法的区别与差异 点击次数:   更新时间:17/12/05 18:04:12     来源:www.kulunfenxiyi.com [关闭] 分    享: 水分仪的使用,是我们检 ...

  9. 干支记年法 在我国古代和近代,一直采用干支法纪年。它采用10天干和12地支配合,一个循环周期为60年。

    /* 干支记年法在我国古代和近代,一直采用干支法纪年.它采用10天干和12地支配合,一个循环周期为60年.10天干是:甲,乙,丙,丁,戊,己,庚,辛,壬,癸12地支是:子,丑,寅,卯,辰,巳,午,未, ...

最新文章

  1. Sql server Insert执行的秘密(下) 带外键的INSERT分析
  2. android启动服务的生命周期,android Service启动运行服务 生命周期
  3. Android TabLayout(选项卡布局)简单用法实例分析
  4. LPCTSTR 与 int 的互相转换
  5. gson json转map_Java几种常用JSON库性能比较
  6. python自动保存图片_Python学习笔记:利用爬虫自动保存图片
  7. electron 解压zip_node.js实现简单的压缩/解压缩功能示例
  8. 关于5G被激烈讨论的那些争端和冲突
  9. 老实人一般容易吃亏,但是老实人遇到的机会比别人多一点点!
  10. SpringCloud 实战:禁止直接访问后端服务
  11. 微软公有云魅力之Traffic Manager
  12. P1603 斯诺登的密码-字符串加法的妙用
  13. 2021年危险化学品经营单位主要负责人考试报名及危险化学品经营单位主要负责人新版试题
  14. c语言中怎么避免整数除法,大整数除法
  15. 如何使用Three.js为3D模型构建Color Customizer应用
  16. 程序存储器编址及程序执行顺序
  17. c语言iq测试,IQ智商测试题
  18. jzoj 4399: 加减乘除模五则运算
  19. Python实现NBA文字直播间
  20. 怎么调整照片dpi大小?如何提高图片的dpi分辨率?

热门文章

  1. x requested with php,PHP / Ajax“Vary:X-Requested-With”对我不起作用!
  2. 小学生html教程,一个在加华人妈妈整理的30个小学生学习网站
  3. 【TP5】无极限分类(树状型)
  4. php实现分时线图,史上最全分时图买卖点图解(转发收藏)!
  5. 最小二乘擬合matlab,存在已知协方差情况下的最小二乘解
  6. android分析内存工具,Android Studio内存泄漏分析工具汇总
  7. Python从入门到精通— 初识Python
  8. 叶筱静受邀主持北大“2019数字新金融领袖峰会”圆桌论坛
  9. 【游戏开发实战】Unity使用ShaderGraph配合粒子系统,制作子弹拖尾特效(Fate/stay night金闪闪的大招效果)
  10. 密码学之分组密码设计及DES算法设计