叶子结点

数据结构与算法(4)树

本秂侑毒 提交于 2020-03-13 07:33:22
树的基本概念: 1、结点的度 结点的度是子结点的个数。例如:结点1有三个字结点2,3,4,所以结点1的度为3。 2、树的度 树的度等于所有结点度中度最高的值。例如:上图中结点度最高为3,所以树的度为3。 3、叶子结点 叶子结点是度为0的结点即没有子结点的结点。例如:上图中3,5,6,7,9,10。 4、分支结点 分支结点是除了叶子结点,树中的其他所有结点。例如:上面树的分支结点为1,2,4,8。 5、内部结点 内部结点是除了根结点以及叶子结点或在分支结点的基础之上在去掉根结点。例如:上面树的内部结点为2,4,8。 6、父结点、子结点、兄弟结点 父节点、子结点和兄弟结点是相对而言的。例如:结点1是结点2,3,4的父节点,结点2,3,4也是结点1的子结点,结点2,3,4又是兄弟结点。 7、层次 图中我们已经表出来了,根为第一层,根的孩子为第二层,依此类推,若某结点在第i层,则其孩子结点在第i+1层。 树的遍历 1、前序遍历 基本思想:前序遍历就是先访问根结点,再访问叶子结点。 图中树的前序遍历为:1,2,5,6,7,3,4,8,9,10。 2、后序遍历   基本思想:本后序遍历就是先访问子结点,再访问根结点。 图中树的后序遍历为:5,6,7,2,3,9,10,8,4,1。 3、层次遍历 基本思想:从第一层开始,依此遍历每层,直到结束。 图中树的层次遍历为:1,2,3,4,5,6,7,8

数据结构--树--总结

回眸只為那壹抹淺笑 提交于 2020-03-13 07:24:51
数据结构——树 定义:树是一个n(n>=0)个结点的有序合集 名词理解: 结点:指树中的一个元素; 结点的度:指结点拥有的子树的个数,二叉树的度不大于2; 数的度:指树中的最大结点度数; 叶子:度为0的结点,也称为终端结点; 高度:叶子节点的高度为1,根节点高度最高; 层:根在第一层,以此类推; 二叉树的定义:由一个结点和两颗互不相交、分别称为这个根的左子树和右子树的二叉树构成(递归定义) 二叉树的性质: 1:二叉树的第i层上至多有2^(i-1)个结点 2:深度为k的二叉树,至多有2^k-1个结点 满二叉树:叶子节点一定要在最后一层,并且所有非叶子节点都存在左孩子和右孩子; 最特别的二叉树:完全二叉树:从左到右、从上到下构建的二叉树; 完全二叉树的性质: 1:结点 i 的子结点为2*i 和 2*i+1(前提是都小于总结点数) 2:结点 i 的父结点为 i/2 二叉树的遍历(要有递归的思想!!!): 1:先序遍历:根->左子树->右子树(先序) 2:中序遍历:左子树->根->右子树(中序) 3:后序遍历:左子树->右子树->根(后序) 这三种遍历方法只是访问结点的时机不同,访问结点的路径都是一样的,时间和空间复杂度皆为O(n) 二叉树的存储结构: 1:顺序存储(只适用于完全二叉树)—— 可以用于排序算法中的堆排序 2:链式存储(最普遍的存储方式)——由于结点可能为空

树与二叉树 | 哈夫曼树

半世苍凉 提交于 2020-03-12 04:43:33
哈夫曼树定义 (01) 路径和路径长度 定义 :在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。 例子 :100和80的路径长度是1,50和30的路径长度是2,20和10的路径长度是3。 (02) 结点的权及带权路径长度 定义 :若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。 例子 :节点20的路径长度是3,它的带权路径长度= 路径长度 * 权 = 3 * 20 = 60。 (03) 树的带权路径长度 定义 :树的带权路径长度规定为所有叶子结点的带权路径长度之和,记为WPL。 例子 :示例中,树的WPL= 1* 100 + 2* 80 + 3* 20 + 3* 10 = 100 + 160 + 60 + 30 = 350。 哈夫曼树 哈夫曼树又称最优二叉树。它是 n 个带权叶子结点构成的所有二叉树中,带权路径长度 WPL 最小的二叉树。 哈夫曼树的构造过程: 给定的n个权值{W1,W2,…,Wn}构造n棵只有一个叶结点的二叉树,从而得到一个二叉树的集合F={T1,T2,…,Tn}。 在F中选取根结点的权值最小和次小的两棵二叉树作为左、右子树构造一棵新的二叉树

【数据结构】查找

风流意气都作罢 提交于 2020-03-11 23:15:00
平均查找长度(ASL, Average Search Length): 在查找过程中,一次查找的长度是指需要比较的关键字次数,而平均查找长度则是所有查找过程中进行关键字比较次数的平均值,(即 ASL= \(\sum\) 查找概率*比较次数 )(一般为等概率1/n) 静态查找表: 查找表的操作无需动态地修改查找表,如 顺序查找、折半查找、散列查找等。 动态查找表: 需要动态地插入或删除的查找表,如 二叉排序树、二叉平衡树、B树、散列查找等。 线性结构 顺序查找 适用条件: 适用于 线性表 基本思想: 从线性表的一段开始,逐个检查关键字是否满足给定的条件。若查找到某个元素的关键字满足给定的条件,则查找成功,返回该元素在线性表中的位置;若已经查找到表的另一端,但还没有查找到符合给定条件的元素,则返回查找失败的信息。 具体实现: typedef struct { //查找表的数据结构 ElemType *data; //元素空间基址,建表时按实际长度分配,0号单元留空 int length; //表的长度 }List; //Sequential Search Table //在顺序表L中顺序查找关键字为key的元素。若找到则返回该元素在表中的位置 int Search_Seq(List L, ElemType key) { L.data[0] = key; //“哨兵” for(i = L

[STL]heap和priority_queue

主宰稳场 提交于 2020-03-11 21:59:22
一.heap 在STL中,priority_queue(优先权队列)的底层机制是最大堆,因此有必要先来了解一下heap。heap采用完全二叉树的结构,当然不是真正的binary tree,因为对于完全二叉树,我们通常用一个数组来表示。 以下几个算法都是STL的泛型算法,包含在头文件algorithm里,priority_queue的push(),pop()都有直接调用它们。 1.push_heap算法 首先,将新元素插入到底层vector的end()处。为了满足最大堆原理(每个结点的值必须大于或等于其子结点的值),于是将新结点与其父亲结点比较,如果其值大于父亲结点,就交换父子结点,直到不需要交换或者它已经到达根结点为止。 2.pop_heap算法 因为作为最大堆,根结点即为最大值。交换vector首尾(first和last)元素,并重新调整[first,last-1)部分,也就是将“新根结点”跟其较大子结点交换,并持续下放,知道叶子结点为止。注意,pop_heap之后,最大元素只是被放在底部容器的最尾端,并没有被取走。若要取走,可用vector的pop_back()函数。 3.sort_heap算法 持续对整个heap做pop_heap操作,每次将操作范围从后向前缩减一个元素,于是我们得到一个递增序列。显然,排序后的heap不是一个合法的heap了。 4.make_heap算法

走远了吗. 提交于 2020-03-11 10:57:34
树是由结点或顶点和边组成的(可能是非线性的)且不存在着任何环的一种数据结构。 基本概念 : 1)兄弟结点——拥有同一个父结点的结点; 2)孩子、双亲——结点的子树的根称为该节点的孩子,相应地,该节点称为孩子的双亲; 3)结点的度——一个结点所包含子树的数量; 4)树的度——该树所有结点中最大的度; 5)叶子结点——树中度为零的结点,也叫终端结点; 6)结点的层数——从根结点开始算,根结点是第一层,依次往下。 7)树的深度——树中结点的最大层数 8)有序树——树中的各结点的 子树(兄弟结点 )从左到右按一定次序去排列的树; 9)森林—— m(m>=0) 棵 互不相交 的树的集合。    存储结构: 1)双亲表示法——在每个结点的结构中,附设一个字段记录其双亲结点在数组中的位置 结点结构如图 : , data是数据域,存储节点的数据信息,parent是指针域,存储该节点的双亲在数组中的下标 /*树的双亲表示法节点结构定义*/ #define MAX_TREE_SIZE 100 typedef int TElemType /*树结点数据类型,目前暂定为整型*/ typedef struct PTNode/*结点数据结构*/ { TElemType data; /*结点数据*/ int parent; /*双亲位置*/ }PTNode; typedef struct/*树结构*/ {

数据结构——B树、B+树、B*树

余生长醉 提交于 2020-03-11 01:36:00
目录 (一)B树(B-树) 1、二叉搜索树 2、B树的基本概念 3、m阶B树的性质 4、B树和二叉树的操作比较 (二)B+树 1、B+树的基本概念 2、B+树的特征 3、B+的优势 (三)B*树 1、B*树的基本概念 2、B*树特点 (一)B树(B-树) 1、二叉搜索树   二叉搜索树有如下特点: 所有非叶子结点至多拥有两个孩子(Left和Right) 所有结点存储一个关键字 非叶子节点的左指针指向小于其关键字的子树,右指针指向大于其关键字的子树   二叉树的搜索,从根节点开始若查询的关键字与节点关键字相等则命中;否则若关键字比结点关键字小则进入左孩子;如果比结点关键字大,就进入右孩子;若左孩子或有孩子的指针为空,则报告未找到该关键字。 2、B树的基本概念   B树(一种多路搜索树,不一定是二叉)的出现是因为磁盘 IO ,IO操作的效率很低,在大量数据存储中(一般用于数据库索引,查找效率较高),查询时我们不能一下将所有数据都加载到内存中,只能逐一加载磁盘页,每个磁盘页对应树的结点。造成大量磁盘 IO 操作(最坏情况下为树的高度),平衡二叉树由于树的深度过大造成磁盘 IO读写频繁所耗费时间长,导致效率低 。       &   磁盘 IO 与预读 emsp; 磁盘读取以靠机械运动,分为寻道时间、旋转延迟、传输时间三个部分,这三个部分耗时相加为一次磁盘 IO 的时间,大概9ms

算法与数据结构学习(35)-树结构(二叉树结点的删除)

拟墨画扇 提交于 2020-03-09 15:21:06
二叉树-删除节点 要求 1.如果删除的节点是叶子节点,则删除该节点 2.如果删除的节点是非叶子节点,则删除该子树. 3.测试,删除掉 5号叶子节点 和 3号子树. 完成二叉树删除结点的操作: 规定: 1.如果删除的节点是叶子节点,则删除该节点 2.如果删除的节点是非叶子节点,则删除该子树. 思路: 首先先处理: 考虑如果树是空树root,如果就只有一个root结点,则将二叉树置空 //然后进行下面的操作 1.因为我们的二叉树是单向的,所以我们是判断当前结点的子节点是否是需要删除的结点,而不能判断当前的结点是不是需要删除的结点 2.如果当前的结点的做子节点不为空,并且左子节点就是要删除的结点,就将this.left = null;并且返回(递归删除结束) 3.如果当前结点的右子节点不为空,并且右子节点就是要删除的结点,就爱那个this.right = null;并且就返回(结束递归删除) 4.如果第2步和第3步没有删除结点,那我们就需要向左子树递归删除 5.如果第4不也没有 删除结点,则应当向右子树进行递归删除。 来源: CSDN 作者: 九岁ya 链接: https://blog.csdn.net/mzc_love/article/details/104750332

王道计算机机试练习——哈夫曼树

筅森魡賤 提交于 2020-03-09 15:06:41
王道计算机机试——哈夫曼树 题目描述 哈夫曼树,第一行输入一个数 n,表示叶结点的个数。需要用这些叶结点生 成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即 weight,题目需要输出 所有结点的值与权值的乘积之和。 1. 哈夫曼树求法 1)将所有结点放入集合 K。 2)若集合 K 中剩余结点大于 2 个,则取出其中权值最小的两个结点, 构造他 们同时为某个新节点的左右儿子,该新节点是他们共同的双亲结点,设定它的权 值为其两个儿子结点的权值和。并将该父亲结点放入集合 K。重复步骤 2 或 3。 3)若集合 K 中仅剩余一个结点, 该结点即为构造出的哈夫曼树数的根结点, 所有构造得到的中间结点 (即哈夫曼树上非叶子结点 )的权值和即为该哈夫曼树 的带权路径和。 为了方便快捷高效率的求得集合 K 中权值最小的两个元素,我们需要使用堆数 据结构。它可以以 O(logn)的复杂度取得 n 个元素中的最小元素。为了绕过对 堆的实现,我们使用标准模板库中的相应的标准模板 ——优先队列。 2.大顶堆与小顶堆 priority_queue < int > Q ; 建立一个保存元素为 int 的堆 Q,但是请特别注意这样建立的堆其默认为大 顶堆,即我们从堆顶取得的元素为整个堆中最大的元素。而在求哈夫曼树中,我 们恰恰需要取得堆中最小的元素,于是我们使用如下语句定义一个小顶堆: priority

PAT A1106 Lowest Price in Supply Chain

被刻印的时光 ゝ 提交于 2020-03-08 22:28:46
问题链接: https://pintia.cn/problem-sets/994805342720868352/problems/994805362341822464 题意: 给出一棵销售供应树,树根唯一。在树根处货物的价格为P,然后从根结点开始每往子结点走一层,该层的货物价格将会在父亲结点的价格上增加r%。求叶子结点处能获得的最低价格,以及能提供最低价格的叶子结点个数。 Note: 1 本题深度初始值为0。 2 r是百分号 要注意除以100 #include<cstdio> #include<iostream> #include<vector> #include<cmath> using namespace std; const int maxn = 100010; int n; double p, r; vector<int> child[maxn]; int lownum = 0; int lowdepth = maxn; void DFS(int index, int depth){ if(child[index].size() == 0){ if(depth < lowdepth){ lowdepth = depth; lownum = 1; }else if(depth == lowdepth){ lownum ++; } } for(int i = 0; i <