叶子结点

【2019.9.17】Za

本小妞迷上赌 提交于 2019-11-29 22:15:56
Za yyb Fibonacci的性质 \(gcd(f[i],f[i+1])=1\) 证明 \(gcd(f[i],f[i+1])\) \(=gcd(f[i+1]-f[i],f[i])\) \(=gcd(f[i-1],f[i])\) \(=....\) \(=gcd(f[1],f[2])=1)\) \(f[m+n]=f[m−1]f[n]+f[m]f[n+1]f[m+n]=f[m−1]f[n]+f[m]f[n+1]\) \(gcd(f[n+m],f[n])=gcd(f[n],f[m])gcd(f[n+m],f[n])=gcd(f[n],f[m])\) 由上面式子得到 \(gcd(f[n+m]=f[m−1]f[n]+f[m]f[n+1],f[n])gcd(f[n+m]=f[m−1]f[n]+f[m]f[n+1],f[n])\) \(=gcd(f[n+1]f[m],f[n])=gcd(f[n+1]f[m],f[n])\) \(=gcd(f[n+1],f[n])∗gcd(f[m],f[n])=gcd(f[n+1],f[n])∗gcd(f[m],f[n])\) \(=1∗gcd(f[m],f[n])=1∗gcd(f[m],f[n])\) \(=gcd(f[m],f[n])\) \(gcd(f[n],f[n+m])=f[gcd(n,n+m)]gcd(f[n],f[n+m])=f[gcd(n,n

avl树的插入操作和删除操作

对着背影说爱祢 提交于 2019-11-29 21:05:55
avl树相比于搜索二叉树每个结点是多了个平衡因子bf,avl树时时刻刻要维持树中的每个结点的平衡因子的绝对值小于等于1. avl树的插入操作: avl树因为要保证每个结点的平衡因子要时时刻刻都符合要求,则树中每插入一个结点,都可能引起平衡被打破,所以每次插入一个结点,都要从插入的结点往上进行检查是否有哪个结点需要调整. 要在插入新结点后进行平衡检查,则需要把插入结点的插入过程的下行路线上的每一个结点都依次记录下来,这个可以借助于栈来实现,在查找插入位置的过程,把每一个结点指针放入栈中. 现在来说一下具体的过程: 从根结点开始,首先查找要插入的位置 : 如果结点值相等则返回错误,如果小于则向左走,如果大于则向右走,把这个过程中的每一个结点都放入一个栈中,这样直到到达叶子结点,即找到了插入的位置.然后new出来一个结点进行插入(如果这个位置的父亲结点(stack中的top)是NULL,则是空树,让root指针指向该结点,插入完成,如果父亲结点不是NULL,则根据父亲结点和本结点的值的大小确定是左边插入还是右边插入). 插入完成以后进行平衡调整 : 取出栈中的元素进行检查:插入的结点对于取出的结点如果是左边插入,则平衡因子减1,如果右边插入则平衡因子加1. 如果加减1以后平衡因子是0,即意味着插入节点之前平衡因子只能是正负1,插入该节点以后,该子树的左右子树高度相等

树、图、排序查找重要算法(960算法)

老子叫甜甜 提交于 2019-11-29 17:09:09
设计求T的WPL的算法:   (1) .给出二叉树结点的数据类型定义;   (2) .给出C语言描述算法;   【 1 】: typedef struct node { int weight; struct node *left,*right; //指向结点左右子女的指针 }BiNode,*BiTree;   【 2 】: int WPL=0; void inorder(BiTree bt,level lv) //bt是二叉树,lv是结点的层次,初值为1 { if(bt) {inorder (bt->left,lv+1); //中序遍历左子树 if(bt->left==null &&bt->right==null) //判断该结点是否为叶子 WPL+=(lv-1)*bt->weight; //累加结点带权路径长度 inorder(bt->right,lv+1); } } 【先序遍历】 NLR (递归) void PreOrder(BiTree T){ if(T!=NULL){ visit(T); //访问根结点 PreOrder(T->lchild); //递归遍历左子树 preOrder(T->rchild); } } 【中序遍历】 LNR (递归) void InOrder(BiTree T){ if(T!=NULL){ InOrder(T->lchild); visit(T)

二叉树算法题

断了今生、忘了曾经 提交于 2019-11-29 15:20:30
二叉树层次遍历 //思路 特殊情况 ,根节点为null,深度为0,return 0 借助队列,队列储存每一层的所有节点, 先保存数组长度,用于控制依次遍历循环——遍历每一个节点保存值,该节点的所有子结点从队尾入队,访问过的节点从头出队 注意——需要先把width存下来,用于for循环的结束标志,因为for循环里面直接操作了queue,不能去都不敢动态获取 队列初始值为root,对每一层都要进行上述遍历——while循环控制,队列空代表叶节点这一层遍历完成,此时遍历结束,退出循环 每次循环开始前初始化一个curNodes储存该层所有节点,每次循环结束,将curNodes压入result var levelOrder = function(root) { if (root === null) return []; //空树 var result = [], queue = [root]; while (queue.length) { let width = queue.length; //需要先把width存下来,用于for循环,for循环里面直接操作了数组 let curNodes = []; for (let i = 0; i < width; i++) { let node = queue.shift(); curNodes.push(node.val); node.left ?

数据结构与算法之排序详解 一点课堂(多岸学院)

时光毁灭记忆、已成空白 提交于 2019-11-29 15:20:18
通过前面的知识,我们已经知道,有序的数据在查找时有极大的性能提升。很多查找都基于有序数据,但并不是所有的结构都能像二叉排序树一样,在插入数据时就已经排好序,很多时候往往是无序的数据,需要我们使用时再进行排序,这就意味着我们需要寻找高效率的排序算法。接下来,我们对当下使用较为普遍的几个算法逐一进行分析。这里推荐一个可以查看算法运行动态过程的网站,加深对算法原理的理解。 基础知识 排序定义 假设含有n个记录的序列为{r1. r2, ..., rn},其相应的关键字分别为{k1, k2, ..., kn},需确定1, 2, ..., n的一种排列p1, p2, ..., pn,使其相应的关键字满足kp1≤kp2≤...≤kpn(非递减或非递增) 关系,即使得序列成为一个按关键字有序的序列{rp1, rp2, ..., rpn} , 这样的操作就称为排序。 稳定性 假设ki=kj( 1≤i≤n, 1≤j≤ n, i≠j ) ,且在排序前的序列中 ri 领先于 rj (即i<j) 。如果排序后 ri 仍领先于 rj,则称所用的排序方法是稳定的;反之,若可能使得排序后的序列中 rj 领先 ri,则称所用的排序方法是不稳定的。 简单来说,就是对于原数据中相等的数据,排序前后如果相对位置没有改变,就是稳定的。 内排序与外排序 内排序是在排序整个过程中,待排序的所有记录全部被放置在内存中

二叉树的遍历

那年仲夏 提交于 2019-11-29 11:10:28
目录 一、二叉树的遍历 1.1 先序遍历 1.2 中序遍历 1.3 后序遍历 1.4 小结 二、二叉树的非递归遍历 2.1 中序遍历非递归遍历算法 2.2 先序遍历的非递归遍历算法 三、层序遍历 3.1 队列实现 四、实际应用 4.1 遍历二叉树的应用:输出二叉树中的叶子节点 4.2 求二叉树的高度 4.3 二元运算表达式树及其遍历 4.4 由两种遍历序列确定二叉树 一、二叉树的遍历 1.1 先序遍历 遍历过程为: 访问 根结点 先序 遍历其左子树; 先序 遍历其右子树。 /* c语言实现 */ void PreOrderTraversal (BinTree BT) { if (BT) { printf("%d", BT->Data); PreOrderTraversal(BT->Left); PreOrderTraversal(BT->Right); } } 先序遍历: A (B D F E)(C G H I) 1.2 中序遍历 遍历过程为: 中序 遍历其 左子树 ; 访问 根节点 ; 中序 遍历其 右子树 。 /* c语言实现 */ void InOrderTraversal (BinTree BT) { if (BT) { InOrderTraversal(BT->Left); printf("%d", BT->Data); InOrderTracersal(BT-

线段树总结

こ雲淡風輕ζ 提交于 2019-11-29 08:31:55
参考题目:A Simple Problem with Integers POJ-3468 距离上一次写这道题已经过去两个月了,前天打模拟赛时连线段树都手敲不出来了。所以这次重新来复习一下线段树。 这次主要是记录一下对线段树区间修改的理解: 一开始我们先是理解线段树的建树原理以及查询原理。利用一个二叉树建立,每个父节点可以记录左右子结点的和或者最大值,以此来维护区间内容。 查询也类似,通过递归寻找,找到所有符合条件(区间内深度最浅)结点,然后将其求和返回或者求最大值返回。 而在之后有单点修改。单点修改重建树来理解,就是递归,找到范围(l,r) ,l=r 时的结点位置更新并 push_up() 向上建树。 但是对于大量数据查询,以及面对区间修改问题时,要一个一个找到位置再更新push_up()就会非常费时间。 所以我们试想能否使用一个标记 tag 传递,在更新范围内的结点就把 tag 传递下去,然后对所有含有tag 的叶子结点更新,再push_up(); 但是对于上面实际上还有更加优化的方案:即 lazy[] 标记。我们用 lazy[]标记记录每个结点修改信息,就像上面一样。但是当递归到某个完全被包含于查询区间的 部分时,我们直接对这个区间更新 即 (r-l+1) * lazy[p] . (完全被包含,所以直接乘以长度即可),单接下来我就直接返回了,不往下递归了

红黑树原理及平衡二叉树旋转详解_一点课堂(多岸学院)

孤者浪人 提交于 2019-11-29 06:03:14
红黑树 树的介绍 树具有的特点有: (1)每个结点有零个或多个子结点 (2)没有父节点的结点称为根节点 (3)每一个非根结点有且只有一个父节点 (4)除了根结点外,每个子结点可以分为多个不相交的子树 名词理解: 结点:指树中的一个元素; 结点的度:指结点拥有的子树的个数,二叉树的度不大于2; 叶子:度为0的结点,也称为终端结点; 高度:叶子节点的高度为1,根节点高度最高; 父节点:若一个节点含有子节点,则这个节点称为其子节点的父节点 子节点:子节点是父节点的下一层节点。 - 节点的层次:从根节点开始,根节点为第一层,根的子节点为第二层,以此类推 - 兄弟节点:拥有共同父节点的节点互称为兄弟节点 度 树的深度(Depth)或高度是树中结点的最大层次。 二叉树 二叉树是每个结点最多有两个子树的树结构。 它有五种基本形态:二叉树可以是空集;根可以有空的左子树或右子树;或者左、右子树皆为空。 为什么需要平衡二叉树? 为了避免这种情况的发生,我们希望可以有一种算法,将我们的不平衡的二叉排序树转化为平衡二叉排序树。这样就可以让我们的二叉排序树结构最优化。 平衡因子 该节点左子树的高度-该节点右子树的高度,既左右子树高度之差。 平衡二叉树旋转 LL型 LR型 RR型 一次旋转调整 RL型 第一次旋转,RR型 第二旋转,RR型进行调整 情况一 添加新节点3 按照LL型,进行一次右旋调整 情况二

二叉树

旧巷老猫 提交于 2019-11-29 05:11:54
前言 树是数据结构中的重中之重,尤其以各类二叉树为学习的难点。一直以来,对于树的掌握都是模棱两可的状态,现在希望通过写一个关于二叉树的专题系列。在学习与总结的同时更加深入的了解掌握二叉树。本系列文章将着重介绍一般二叉树、完全二叉树、满二叉树、 线索二叉树 、 霍夫曼树 、 二叉排序树 、平衡二叉树、红黑树、B树。希望各位读者能够关注专题,并给出相应意见,通过系列的学习做到心中有“树”。 1 重点概念 1.1 结点概念 结点是数据结构中的基础,是构成复杂数据结构的基本组成单位。 1.2 树结点声明 本系列文章中提及的结点专指树的结点。例如:结点A在图中表示为: 2 树 2.1 定义 树(Tree)是n(n>=0)个结点的有限集。n=0时称为空树。在任意一颗非空树中: 1)有且仅有一个特定的称为根(Root)的结点; 2)当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、......、Tn,其中每一个集合本身又是一棵树,并且称为根的子树。 此外,树的定义还需要强调以下两点: 1)n>0时根结点是唯一的,不可能存在多个根结点,数据结构中的树只能有一个根结点。 2)m>0时,子树的个数没有限制,但它们一定是互不相交的。 示例树: 图2.1为一棵普通的树: 图2.1 普通树 由树的定义可以看出,树的定义使用了递归的方式。递归在树的学习过程中起着重要作用

红黑树(自平衡的二叉查找树)

放肆的年华 提交于 2019-11-29 04:54:48
30张图带你彻底理解红黑树 红黑树怎么自平衡?什么时候需要左旋或右旋?插入和删除破坏了树的平衡后怎么处理? 红黑树定义和性质 红黑树是一种 含有红黑结点并能自平衡的二叉查找树 。它必须满足下面性质: 性质1:每个节点要么是黑色,要么是红色。 性质2: 根节点 是 黑色 。 性质3:每个 叶子节点 (NIL)是 黑色 。 性质4:每个 红色结点的两个子结点 一定都是 黑色 。 性质5: 任意一结点到每个叶子结点 的路径都 包含数量相同的黑结点 。 性质5.1:如果 一个结点存在黑子结点 ,那么 该结点肯定有两个子结点 (在Java中, 叶子结点 是 为null 的结点。) 图1就是一颗简单的红黑树。其中Nil为叶子结点,并且它是黑色的。(值得提醒注意的是,在Java中,叶子结点是为null的结点。) 红黑树并 不是 一个 完美平衡(左右子树高度相差为0)二叉查找树 ,从图1可以看到,根结点P的左子树显然比右子树高,但左子树和右子树的 黑结点的层数是相等的 ,也即 任意一个结点到到每个叶子结点的路径都包含数量相同的黑结点 (性质5)。所以我们叫红黑树这种平衡为 黑色完美平衡 。 我们把 正在处理(遍历)的结点 叫做 当前结点 ,如图2中的D,它的父亲叫做父结点,它的父亲的另外一个子结点叫做兄弟结点,父亲的父亲叫做祖父结点。 红黑树自平衡 红黑树能自平衡,它靠的是什么?三种操作: 左旋