版权声明:本文为博主原创文章,未经博主允许不得转载! https://blog.csdn.net/weixin_42839965/article/details/82319631
逻辑结构
线性:
数组:
链表:
栈和队列是一种特殊的线性结构;
循环队列的核心是数组;
非线性:
树:
定义:
1、有且只有一个称为根的节点;
2、有若干个互不相交的子树,这些子树本身也是一棵树;
通俗的定义:
1、树是由节点和边组成的;
2、每一个节点只有一个父节点但可以有多个子节点;
3、但有一个节点例外,该节点没有父节点,此节点称为根节点;
专业术语:
节点 父节点 子节点
子孙 堂兄弟
深度:
树中节点的最大层次;
从根节点到最底层节点之间的层数称为深度;
根节点是第一层;
叶子节点:
没有子节点的节点;
非终端节点:
实际就是非叶子节点;
根节点既可以是叶子节点,也可以是非叶子节点;
度:
子节点的个数称为度(含有最大节点的个数称为该节点的度);
分类:
一般树:
任意一个节点子节点的个数都不受限;
二叉树:
任意一个节点的子节点个数最多两个,且子节点的位置不可更改;
分类:
一般二叉树:
满二叉树:
在不增加树的层数的前提下,无法再多添加一个节点的二叉树就是满二叉树
完全二叉树:
如果只是删除了满二叉树最底层最右边的连续若干个节点,这样形成的二叉树就是满二叉树;
完全二叉树的一个特例是:满二叉树
森林:
n个互不相交的树的集合;
树的存储:
先序遍历、中序遍历、后序遍历存储的线性有效节点无法根据存储的顺序恢复出树的原状
二叉树的存储
连续存储[完全二叉树]
优点:
查找某个节点的父节点和子节点(包括判断有没有子节点)速度快;
缺点:
耗用内存空间过大
链式存储
构成结构:指针域+数据域+指针域构成一个节点;
一般树的存储:
双亲表示法:
内部以数组的形式表示;
求父节点方便;
孩子表示法:
求子节点方便;
双亲孩子表示法:
求父节点和子节点都很方便;
二叉树表示法:
把一个普通树转化为二叉树来存储;
具体转化方法:
设法保证任意一个节点的
左指针域指向它的第一个孩子
右指针域指向它的兄弟
只要能满足此条件,就能将一个普通树转化为二叉树;
一个普通树转化成的二叉树一定没有右子树;
森林的存储
先将森林转化成二叉树存储;
操作:
树的遍历:
先序遍历:中→左→右(先访问根节点)
先访问根节点,
再先序访问左子树,
再先序访问右子树;
中序遍历:左→中→右(中间访问根节点)
中序遍历左子树,
再访问根节点,
再中序遍历右子树;
后序遍历:左→右→中(最后访问根节点)
先中序遍历左子树,
再中序遍历右子树,
再在访问根节点;
已知两种遍历序列求原始二叉树;
通过先序和中序、中序和后续可推断出原始二叉树;
但是通过先序和后序无法还原原始二叉树;
例题1:已知先序和中序求后序
先序:ABCDEFGH
中序:BDCEAFHG
求后序;
后序:DECBHGFA
分析:先序中先出现的是根节点,因此A是根节点;
根据中序可知,BDCE是左子树,FHG是右子树,
再根据先序中B先出现,所以B是根的左子树的根节点,
以此类推,先序中先出现的是根节点,中序确定左、右子树;
总结:先根据先序确定根,再根据中序确定左、右子树;
例题2:
先序:ABDGHCEFI
中序:GDHBAECIF
求后序;
后序:GHDBEIFCA
分析:确定B节点的位置后,中序遍历中B紧靠根节点A,所以节点B没有右子树;
总结:先根据先序确定根,再根据中序确定左、右子树;
已知中序和后序求先序
例题1:已知先序和中序求后序
中序:BDCEAFHG
后序:DECBHGFA
求先序;
先序:ABCDEFGH
分析:后序中,最后为根节点,可将中序分为根节点的两部分:左子树、右子树;
BCDE是A的左子树,FGH是A的右子树,再根据后序中左子树最后出现的就是
左子树根节点B;右子树的根节点是F,根据中序中AF紧邻,确定F没有左子树;
应用:
树是数据库中数据组织一种重要形式;
操作系统子父进程的关系本身就是一种树;
面向对象语言中类的继承关系本身是一棵树;
赫夫曼树