叶子结点

平衡二叉树(AVL Tree)

半世苍凉 提交于 2019-11-27 12:06:53
在学习算法的过程中,二叉平衡树是一定会碰到的,这篇博文尽可能简明易懂的介绍下二叉树的相关概念,然后着重讲下什么事平衡二叉树。 (由于作图的时候忽略了箭头的问题,正常的树一般没有箭头,虽然不影响描述的过程,但是还是需要注意,所以还请读者忽略一下部分图的箭头) 一、二叉(查找)树 二叉查找树(Binary Search Tree)是二叉树的一种,其树节点(internal nodes of the tree)储存着键值并且满足以下特性并如图A所示: 假设u, v, r分别为树的三个结点(nodes),r为树的根节点,u为根的左子树,v为根结点的右子树; 键值大小关系:key(u) < key(r) < key(v),也就是位于根结点(亦或是父节点)的左子树的所有结点的值都是小于根或者父结点的,而位于右子树的结点都大于根或者父结点; 树的外部结点不储存任何的信息。 图A 二叉查找树 二、二叉查找树的操作 2.1 查找(Search) 如若要查找二叉树中的某个元素k,我们会从根节点朝着树结构往下寻找对应的结点,所寻找的结点方向取决于当前结点与所要寻找的结点的值的对比。基于图A,假设我们现在所要寻找的结点是7,那么从根结点开始,我们可以知道7 < 8,那么往下朝着结点值为6的子树走,然后我们发现6 < 7所以此时我们就寻找结点为6的右子树,这时我们发现7 = 7

计算二叉树中叶子结点个数的方法

ぐ巨炮叔叔 提交于 2019-11-27 09:44:53
基础知识: 1.二叉树第i层最多有2^(i-1)个结点。 2.深度为k的二叉树至多有2^k-1个结点。 一个完全二叉树有七百个结点,问该二叉树有多少个叶子结点 根据“二叉树的第i层至多有2^(i − 1)个结点;深度为k的二叉树至多有2^k − 1个结点(根结点的深度为1)”这个性质:因为2^9-1 < 700 < 2^10-1 ,所以这个完全二叉树的深度是10,前9层是一个满二叉树,这样的话,前九层的结点就有2^9-1=511个;而第九层的结点数是2^(9-1)=256所以第十层的叶子结点数是700-511=189个;现在来算第九层的叶子结点个数。由于第十层的叶子结点是从第九层延伸的,所以应该去掉第九层中还有子树的结点。因为第十层有189个,所以应该去掉第九层中的(189+1)/2=95个;所以,第九层的叶子结点个数是256-95=161,加上第十层有189个,最后结果是350个。 一个有 800 个结点的完全二叉树,问有_____个叶子结点? 答案:400 来源: http://www.cnblogs.com/faith0217/p/4079520.html

二叉树高度、宽度、结点个数、叶子结点个数

倖福魔咒の 提交于 2019-11-27 09:25:20
实现二叉树宽度递归算法~ 1 #include <iostream> 2 using namespace std; 3 typedef struct node 4 { 5 char data; 6 int lab; 7 struct node *lchild; 8 struct node *rchild; 9 }btree; 10 int m=0; 11 void ct(btree *&b,char *str) 12 { 13 btree *st[99],*p=NULL; 14 int top=-1,k,j=0; 15 char ch; 16 b=NULL; 17 ch=str[j]; 18 while(ch!='\0') 19 { 20 switch(ch) 21 { 22 case '(':top++;st[top]=p;k=1;break; 23 case ')':top--;break; 24 case ',':k=2;break; 25 default:p=(btree *)malloc(sizeof(btree)); 26 p->data=ch; 27 p->lchild=p->rchild=NULL; 28 if(b==NULL) 29 b=p; 30 else 31 { 32 switch(k) 33 { 34 case 1:st[top]->lchild=p

排序算法 - 堆排序(图解)

a 夏天 提交于 2019-11-27 08:45:13
【原文: https://www.cnblogs.com/fortunely/p/10254161.html 】 1.基本概念 堆 ,分为大顶堆(大堆)和小顶堆(小堆),是顺序存储的完全二叉树,并且满足以下特性之一: (1) 任意非终端结点关键字不小于左右子结点(大堆) ki >= k2i+1并且ki>=k2i+2 其中,0 <= i <= (n-1)/2,n是数组元素个数 (2) 任意非终端结点关键字不大于左右子结点(小堆) ki <= k2i+1并且ki<=k2i+2 其中,0 <= i <= (n-1)/2,n是数组元素个数 调整 (也有叫筛选): 从当前结点(要求是非终端结点)开始, 对于大堆,要求当前结点关键字不小于子结点,如不符合,则将最大的子结点与当前结点交换。循环迭代交换后的子树,确保所有子树都符合大堆特性。 小堆调整过程类似。 2.基本思想 堆排序就是利用构建堆和输出堆顶元素的过程,不断对堆进行调整以保证当前结点及其孩子结点满足堆特性,从而达到对初始数组元素进行排序的目的。 大堆通常对应升序序列,小堆通常对应降序排列。 核心步骤: 1)构建堆(大堆/小堆) 从最后一个非终端结点开始,向前进行调整,保证当前结点及其子树符合堆特性; 2) 输出有序序列 交换堆顶与末尾叶子结点,堆顶输出到数组的有序序列末尾,而不参与堆的调整。从交换后的堆顶开始调整

XGBoost学习总结(二)

别等时光非礼了梦想. 提交于 2019-11-27 08:33:23
1_XGBoost原理 \[ \begin{align} X\!G\!Boost&=eXtreme+GBDT\\ &=eXtreme+(Gradient+BDT) \\ &=eXtreme+Gradient+(Boosting+DecisionTree) \end{align} \] \[Boosting \to BDT \to GBDT \to X\!G\!Boost\]   * 提升方法boosting + 决策树DecisionTree --> BDT提升决策树   * BDT + Gradient梯度拟合残差 --> GBDT梯度提升决策树   * GBDT + eXtreme工程优化 --> XGBoost 决策树的表示形式: (1)树形结构,由根结点到叶结点 (2)规则集表示方法,if--else--- (3)回归树 在坐标系中画出回归决策树 (4)用公式表示 决策树的特征选择方法 决策树的剪枝方法 1_1_提升方法(Boosting)   提升方法使用 加法模型 和 前向分步算法 。   加法模型:要求模型要具备可加性(如:决策树)     加法模型 \[f\left(x\right)=\sum_{m=1}^M\beta_m b\left(x;\gamma_m\right) \tag{1.1}\] 其中, \(b\left(x;\gamma_m\right)\)

红黑树的插入、创建和删除

穿精又带淫゛_ 提交于 2019-11-27 07:21:39
文章目录 1.红黑树介绍 2.红黑树的旋转 3.红黑树的插入和创建 4.红黑树的删除 5.参考 1.红黑树介绍    二叉搜索树在最好情况下的时间复杂度是 O ( l o g n ) O(log n) O ( l o g n ) ,但是当插入元素是有序的时候,二叉搜索树就变成了一个链表,在这种情况下,时间复杂度为 O ( n ) O(n) O ( n ) 。    红黑树就是针对这一情形进行改进。红黑树本质上是一种二叉搜索树,但它在二叉搜索树的基础上额外添加了一个标记(颜色),同时具有一定的规则,这些规则使得红黑树保证一种平衡,插入、删除、查找的最坏时间复杂度都为 O ( l o g n ) O(logn) O ( l o g n ) 。红黑树的统计性能要好于平衡二叉树。 红黑树的在原有的二叉搜索树上增加了如下几个要求: 1)每个结点要么是红色,要么是黑色 2)根节点永远是黑色的 3)所有叶子结点都是黑色的(红黑树中的叶子结点都是空结点(NIL)。) 4)每个红色结点的两个子结点一定都是黑色的(说明从根到结点的路径上不会有两个连续的红色结点,但黑色结点可以是连续的) 5)从任一结点到其子树中每个叶子结点的路径都包含相同数量的黑色结点。(是成为红黑树最主要的条件,后序的插入、删除操作都是为了遵守这个规定) 红黑树并不是标准的平衡二叉树,它是以上述要求作为一种平衡方法

jzoj1899. 剪枝

人走茶凉 提交于 2019-11-27 05:59:18
题目描述 Description   给出一棵有根树。树有n个结点,被分别标记成1到n的整数,1号结点为根结点。第i(1≤i≤n)个结点的权值为Wi。对于结点i,它有Ti个孩子,从左到右依次为Pi1,Pi2,…,PiTi。特别地,若i号结点是叶结点,则Ti=0。   我们对树进行深度优先搜索(DFS),每个点必须按从左到右的顺序访问每个孩子,形成一个DFS序列,记作Seq{Seq1,Seq2,…,Seqn}。对于两个叶结点a、b,我们说它们是相邻的,当且仅当不存在另外的叶结点c,在DFS序列中c在a、b之间。换个方式讲,对于叶结点a、b、c,记Seqi=a,Seqj=b(i<j) ,不存在Seqk=c,使得i<k<j。   每对相邻的叶结点(a,b),都存在一个影响值。影响值定义为a到b的路径上(不包含a、b的结点)的最大点权值。   定义一棵树的价值等于这棵树所有叶结点的权值之和减去每对相邻叶结点的影响值。   当然,要是让你算这棵树的价值就太简单了。你的目标是对树进行一些剪枝,使树的价值最大。剪枝的方式为:如果一个结点的孩子都是叶结点,就可以将它所有的孩子剪去。 Input   第1行:n;   第2…n+1行:第i+1行为Wi,Ti,Pi1,Pi2,…,PiTi。 Output   第1行:这棵树修改后的最大价值。 Sample Input 输入样例一】 3 1 2 2 3

【常用数据结构——二叉树(还有三叉四叉...? )】

不打扰是莪最后的温柔 提交于 2019-11-27 05:40:20
---恢复内容开始--- 简介   在计算机科学中,二叉树是每个结点最多有两个子树的有序树。通常子树的根被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用作二叉查找树和二叉堆或是二叉排序树。 基本术语     子树 :除了根节点外,每个子节点都可以分为多个不相交的子树。 孩子与双亲 :若一个结点有子树,那么该结点称为子树根的"双亲",子树的根是该结点的"孩子"。 兄弟 :具有相同双亲的节点互为兄弟。 节点的度 :一个节点拥有子树的数目。 叶子 :没有子树,也即是度为0的节点。 分支节点 :除了叶子节点之外的节点,也即是度不为0的节点。 内部节点 :除了根节点之外的分支节点。 层次 :根节点为第一层,其余节点的层次等于其双亲节点的层次加1. 树的高度 :也称为树的深度,树中节点的最大层次。 有序树 :树中节点各子树之间的次序是重要的,不可以随意交换位置。 无序树 :树种节点各子树之间的次序是不重要的。可以随意交换位置。 森林 :0或多棵互不相交的树的集合。 基本形态 也就五种,从左往右分别是空树,只有根节点的树,根节点和左儿子,根节点和右孩子,根节点和左右孩子。 基本性质 1.二叉树第i层上的结点数目最多为2 i-1 (i>=1) 2.深度为k的二叉树至多有2 k -1个结点(k>=1) 3.包含n个结点的二叉树的高度至少为(log

MySQL性能优化——索引

天涯浪子 提交于 2019-11-27 02:33:01
一、MySQL中索引的语法 1. 创建索引 1. 在创建表的时候添加索引 CREATE TABLE mytable( ID INT NOT NULL, username VARCHAR(16) NOT NULL, INDEX [indexName] (username(length)) ); 2. 在创建表以后添加索引 ALTER TABLE my_table ADD [UNIQUE] INDEX index_name(column_name); 或者 CREATE INDEX index_name ON my_table(column_name); 注意: 1、索引需要占用磁盘空间,因此在创建索引时要考虑到磁盘空间是否足够 2、创建索引时需要对表加锁,因此实际操作中需要在业务空闲期间进行 2. 根据索引查询 具体查询: SELECT * FROM table_name WHERE column_1=column_2;(为column_1建立了索引) 或者模糊查询 SELECT * FROM table_name WHERE column_1 LIKE '%三' SELECT * FROM table_name WHERE column_1 LIKE '三%' SELECT * FROM table_name WHERE column_1 LIKE '%三%' SELECT *

TJU1173

北城以北 提交于 2019-11-27 01:43:18
在思考这题的时候想到了一个很好的解法。 建立一棵用数组模拟的树,每个结点的值类型是一个char,内容是ABC中的一个。先把原01串处理为AB串并作为叶子结点,然后两个两个合并。合并的时候,两结点全A或全B时,父结点值为A或B,否则为C。树建立起来以后,先序遍历即可。注意只有在一个结点的值为C的时候才访问左右孩子。 #include < iostream > #include < cstring > using namespace std; const int K = 0x20000 ; void PrintTree( char s[ 2 * K], int current); int length; int main() { char s[ 2 * K]; int ptEnd,ptStart; while (cin >> s) { ptStart = 0 ; ptEnd = strlen(s); length = ptEnd * 2 - 1 ; for ( int i = 0 ;i < ptEnd;i ++ ) s[i] = s[i] - ' 0 ' + ' A ' ; while (ptStart + 2 <= ptEnd) { if (s[ptStart] != ' C ' && s[ptStart] == s[ptStart + 1 ]) s[ptEnd ++ ] = s