acm培训资料——树与等价问题
信息技术奥赛辅导树与二叉树
D. (k+1)/2
18
满二叉树和完全二叉树 一般应用顺序存储结构 进行数据的存储。
对于非满二叉树,会有 某些编号没有对应的结 点(通常称为“虚结 点”),通常可以用特 殊标记符号(例如:#) 表示虚结点,将树转换 为满二叉树进行存储。
a
b
c
d ef g
hi
j
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 abcdef g###h##i j
现实世界中,能用树的结构表示的例子: 学校的行政关系(P31)、书的层次结构(P32)、人类的家 族血缘关系等。
2
例:下图是一个有13个结点的树,其中A是 根,其余结点为分三个互不相交的子集: T1={B,E,F,K,L} T2={F,G} T3={D,H,I,J,M} T1、T2和T3都是 根A的子树。
二叉树是一种很有用的非线性结构。
二叉树具有以下两个特点: (1)非空二叉树只有一个根结点; (2)每一个结点最多有两棵子树,且分别称
为该结点的左子树与右子树。
5
6 6
二叉树的性质:
性质1:在任意一棵二叉树中,度为0的结点(即
叶子结点)总是比度为2的结点多一个。
例子1:某二叉树中度为2的结点有18个,则该二 叉树中有 19 个叶子结点。
满二叉树是指除最后一层外,每一层上的所有结点都有
两个子结点。
完全二叉树是指这样的二叉树:除最后一层外,每一层
上的结点数均达到最大值;在最后一层上只缺少右边 的若干结点。 注意:满二叉树是完全二叉树,完全二叉树不一定是满 二叉树。
若一棵完全二叉树的结点数n为偶数,则叶子结点 数为结点数除以2(即:n/2),若结点数为奇数,则 叶子结点数为结点数加一再除以2(即:(n+1)/2) 10
数据结构树的知识点总结
数据结构树的知识点总结一、树的基本概念。
1. 树的定义。
- 树是n(n ≥ 0)个结点的有限集。
当n = 0时,称为空树。
在任意一棵非空树中:- 有且仅有一个特定的称为根(root)的结点。
- 当n>1时,其余结点可分为m(m>0)个互不相交的有限集T1、T2、…、Tm,其中每个集合本身又是一棵树,并且称为根的子树(sub - tree)。
2. 结点的度、树的度。
- 结点的度:结点拥有的子树个数称为结点的度。
- 树的度:树内各结点的度的最大值称为树的度。
3. 叶子结点(终端结点)和分支结点(非终端结点)- 叶子结点:度为0的结点称为叶子结点或终端结点。
- 分支结点:度不为0的结点称为分支结点或非终端结点。
- 除根结点之外,分支结点也称为内部结点。
4. 树的深度(高度)- 树的层次从根开始定义起,根为第1层,根的子结点为第2层,以此类推。
树中结点的最大层次称为树的深度(或高度)。
二、二叉树。
1. 二叉树的定义。
- 二叉树是n(n ≥ 0)个结点的有限集合:- 或者为空二叉树,即n = 0。
- 或者由一个根结点和两棵互不相交的、分别称为根结点的左子树和右子树的二叉树组成。
2. 二叉树的特点。
- 每个结点最多有两棵子树,即二叉树不存在度大于2的结点。
- 二叉树的子树有左右之分,次序不能颠倒。
3. 特殊的二叉树。
- 满二叉树。
- 一棵深度为k且有2^k - 1个结点的二叉树称为满二叉树。
满二叉树的特点是每一层上的结点数都是最大结点数。
- 完全二叉树。
- 深度为k的、有n个结点的二叉树,当且仅当其每一个结点都与深度为k的满二叉树中编号从1至n的结点一一对应时,称之为完全二叉树。
完全二叉树的叶子结点只可能在层次最大的两层上出现;对于最大层次中的叶子结点,都依次排列在该层最左边的位置上;如果有度为1的结点,只可能有一个,且该结点只有左孩子而无右孩子。
三、二叉树的存储结构。
1. 顺序存储结构。
- 二叉树的顺序存储结构就是用一组地址连续的存储单元依次自上而下、自左至右存储完全二叉树上的结点元素。
acm知识点
acm知识点转一个搞ACM需要的掌握的算法.要注意,ACM的竞赛性强,因此自己应该和自己的实际应用联系起来.适合自己的才是好的,有的人不适合搞算法,喜欢系统架构,因此不要看到别人什么就眼红,发挥自己的长处,这才是重要的.第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来.1.最短路(Floyd、Dijstra,BellmanFord)2.最小生成树(先写个prim,kruscal要用并查集,不好写)3.大数(高精度)加减乘除4.二分查找. (代码可在五行以内)5.叉乘、判线段相交、然后写个凸包.6.BFS、DFS,同时熟练hash表(要熟,要灵活,代码要简)7.数学上的有:辗转相除(两行内),线段交点、多角形面积公式.8. 调用系统的qsort, 技巧很多,慢慢掌握.9. 任意进制间的转换第二阶段:练习复杂一点,但也较常用的算法。
如:1. 二分图匹配(匈牙利),最小路径覆盖2. 网络流,最小费用流。
3. 线段树.4. 并查集。
5. 熟悉动态规划的各个典型:LCS、最长递增子串、三角剖分、记忆化dp6.博弈类算法。
博弈树,二进制法等。
7.最大团,最大独立集。
8.判断点在多边形内。
9. 差分约束系统.10. 双向广度搜索、A*算法,最小耗散优先.相关的知识图论路径问题0/1边权最短路径BFS非负边权最短路径(Dijkstra)可以用Dijkstra解决问题的特征负边权最短路径Bellman-FordBellman-Ford的Yen-氏优化差分约束系统Floyd广义路径问题传递闭包极小极大距离 / 极大极小距离Euler Path / Tour圈套圈算法混合图的 Euler Path / Tour Hamilton Path / Tour特殊图的Hamilton Path / Tour 构造生成树问题最小生成树第k小生成树最优比率生成树0/1分数规划度限制生成树连通性问题强大的DFS算法无向图连通性割点割边二连通分支有向图连通性强连通分支2-SAT最小点基有向无环图拓扑排序有向无环图与动态规划的关系二分图匹配问题一般图问题与二分图问题的转换思路最大匹配有向图的最小路径覆盖0 / 1矩阵的最小覆盖完备匹配最优匹配稳定婚姻网络流问题网络流模型的简单特征和与线性规划的关系最大流最小割定理最大流问题有上下界的最大流问题循环流最小费用最大流 / 最大费用最大流弦图的性质和判定组合数学解决组合数学问题时常用的思想逼近递推 / 动态规划概率问题Polya定理计算几何 / 解析几何计算几何的核心:叉积 / 面积解析几何的主力:复数基本形点直线,线段多边形凸多边形 / 凸包凸包算法的引进,卷包裹法Graham扫描法水平序的引进,共线凸包的补丁完美凸包算法相关判定两直线相交两线段相交点在任意多边形内的判定点在凸多边形内的判定经典问题最小外接圆近似O(n)的最小外接圆算法点集直径旋转卡壳,对踵点多边形的三角剖分数学 / 数论最大公约数Euclid算法扩展的Euclid算法同余方程 / 二元一次不定方程同余方程组线性方程组高斯消元法解mod 2域上的线性方程组整系数方程组的精确解法矩阵行列式的计算利用矩阵乘法快速计算递推关系分数分数树连分数逼近数论计算求N的约数个数求phi(N)求约数和快速数论变换……素数问题概率判素算法概率因子分解数据结构组织结构二叉堆左偏树二项树胜者树跳跃表样式图标斜堆reap统计结构树状数组虚二叉树线段树矩形面积并圆形面积并关系结构Hash表并查集路径压缩思想的应用STL中的数据结构vectordequeset / map动态规划 / 记忆化搜索动态规划和记忆化搜索在思考方式上的区别最长子序列系列问题最长不下降子序列最长公共子序列最长公共不下降子序列一类NP问题的动态规划解法树型动态规划背包问题动态规划的优化四边形不等式函数的凸凹性状态设计规划方向线性规划常用思想二分最小表示法串KMP Trie结构后缀树/后缀数组 LCA/RMQ有限状态自动机理论排序选择/冒泡快速排序堆排序归并排序基数排序拓扑排序排序网络初期:一.基本算法:(1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586)(3)递归和分治法. (4)递推.(5)构造法.(poj3295) (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:(1)图的深度优先遍历和广度优先遍历.(2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)(3)最小生成树算法(prim,kruskal)(poj1789,poj2485,poj1258,poj3026)(4)拓扑排序 (poj1094)(5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)(6)最大流的增广路算法(KM算法). (poj1459,poj3436)三.数据结构.(1)串 (poj1035,poj3080,poj1936)(2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)(3)简单并查集的应用.(4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)(5)哈夫曼树(poj3253)(6)堆(7)trie树(静态建树、动态建树) (poj2513)四.简单搜索(1)深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)(2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)(3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)五.动态规划(1)背包问题. (poj1837,poj1276)(2)型如下表的简单DP(可参考lrj的书 page149):1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)(poj3176,poj1080,poj1159)3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)六.数学(1)组合数学:1.加法原理和乘法原理.2.排列组合.3.递推关系.(POJ3252,poj1850,poj1019,poj1942)(2)数论.1.素数与整除问题2.进制位.3.同余模运算.(poj2635, poj3292,poj1845,poj2115)(3)计算方法.1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)七.计算几何学.(1)几何公式.(2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031,poj1039)(3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)(poj1408,poj1584)(4)凸包. (poj2187,poj1113)中级:一.基本算法:(1)C++的标准模版库的应用. (poj3096,poj3007)(2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)二.图算法:(1)差分约束系统的建立和求解. (poj1201,poj2983)(2)最小费用最大流(poj2516,poj2516,poj2195)(3)双连通分量(poj2942)(4)强连通分支及其缩点.(poj2186)(5)图的割边和割点(poj3352)(6)最小割模型、网络流规约(poj3308, )三.数据结构.(1)线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)(2)静态二叉检索树. (poj2482,poj2352)(3)树状树组(poj1195,poj3321)(4)RMQ. (poj3264,poj3368)(5)并查集的高级应用. (poj1703,2492)(6)KMP算法. (poj1961,poj2406)四.搜索(1)最优化剪枝和可行性剪枝(2)搜索的技巧和优化 (poj3411,poj1724)(3)记忆化搜索(poj3373,poj1691)五.动态规划(1)较为复杂的动态规划(如动态规划解特别的施行商问题等)(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj303 4)(2)记录状态的动态规划. (POJ3254,poj2411,poj1185)(3)树型动态规划(poj2057,poj1947,poj2486,poj3140)六.数学(1)组合数学:1.容斥原理.2.抽屉原理.3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).4.递推关系和母函数.(2)数学.1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)2.概率问题. (poj3071,poj3440)3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)(3)计算方法.1.0/1分数规划. (poj2976)2.三分法求解单峰(单谷)的极值.3.矩阵法(poj3150,poj3422,poj3070)4.迭代逼近(poj3301)(4)随机化算法(poj3318,poj2454)(5)杂题.(poj1870,poj3296,poj3286,poj1095)七.计算几何学.(1)坐标离散化.(2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)(3)多边形的内核(半平面交)(poj3130,poj3335)(4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)高级:一.基本算法要求:(1)代码快速写成,精简但不失风格(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)(2)保证正确性和高效性. poj3434二.图算法:(1)度限制最小生成树和第K最短路. (poj1639)(2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)(poj3155,poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446(3)最优比率生成树. (poj2728)(4)最小树形图(poj3164)(5)次小生成树.(6)无向图、有向图的最小环三.数据结构.(1)trie图的建立和应用. (poj2778)(2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和在线算法(RMQ+dfs)).(poj1330)(3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移的目的). (poj2823)(4)左偏树(可合并堆).(5)后缀树(非常有用的数据结构,也是赛区考题的热点).(poj3415,poj3294)四.搜索(1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)(2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储状态、双向广搜、A*算法. (poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)(3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大、可以考虑双向搜索或者是轮换搜索、IDA*算法. (poj3131,poj2870,poj2286)五.动态规划(1)需要用数据结构优化的动态规划.(poj2754,poj3378,poj3017)(2)四边形不等式理论.(3)较难的状态DP(poj3133)六.数学(1)组合数学.1.MoBius反演(poj2888,poj2154)2.偏序关系理论.(2)博奕论.1.极大极小过程(poj3317,poj1085)2.Nim问题.七.计算几何学.(1)半平面求交(poj3384,poj2540)(2)可视图的建立(poj2966)(3)点集最小圆覆盖.(4)对踵点(poj2079)八.综合题.(poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj331 5,poj2148,poj1263)。
数据结构-C语言描述(第三版)(陈慧南)章 (6)
第6章 树 例如,设有序表为(21, 25, 28, 33, 36, 43),若要在表中 查找元素36,通常的做法是从表中第一个元素开始,将待查元素 与表中元素逐一比较进行查找,直到找到36为止。粗略地说,如 果表中每个元素的查找概率是相等的,则平均起来,成功查找一 个元素需要将该元素与表中一半元素作比较。如果将表中元素组 成图6-3所示的树形结构,情况就大为改观。我们可以从根结点 起,将各结点与待查元素比较,在查找成功的情况下,所需的最 多的比较次数是从根到待查元素的路径上遇到的结点数目。当表 的长度n很大时,使用图6-3所示的树形结构组织表中数据,可 以很大程度地减少查找所需的时间。为了查找36,我们可以让36 与根结点元素28比较,36比28大,接着查右子树,查找成功。显 然,采用树形结构能节省查找时间。
第6章 树
E
E
A
F
B
G
CD
LJ
M
N
T1
X
YZ
U T2
B
F
A
DC
G
JL
T3 N
M
(a)
(b)
图6-2 树的例子
(a) 树T1和T2组成森林;(b) 树T3
第6章 树
6.2 二 叉 树
二叉树是非常重要的树形数据结构。很多从实际问题中抽 象出来的数据都是二叉树形的,而且许多算法如果采用二叉树 形式解决则非常方便和高效。此外,以后我们将看到一般的树 或森林都可通过一个简单的转换得到与之相应的二叉树,从而 为树和森林的存储及运算的实现提供了有效方法。
第6章 树
图6-1描述了欧洲部分语言的谱系关系,它是一个后裔图, 图中使用的描述树形结构数据的形式为倒置的树形表示法。在 前几章中,我们学习了多种线性数据结构,但是一般来讲,这 些数据结构不适合表示如图6-1所示的层次结构的数据。为了 表示这类层次结构的数据,我们采用树形数据结构。在本章中 我们将学习多种不同特性的树形数据结构,如一般树、二叉树、 穿线二叉树、堆和哈夫曼树等。
程序设计竞赛常用算法
常用算法设计方法要使计算机能完成人们预定的工作,首先必须为如何完成预定的工作设计一个算法,然后再根据算法编写程序。
计算机程序要对问题的每个对象和处理规则给出正确详尽的描述,其中程序的数据结构和变量用来描述问题的对象,程序结构、函数和语句用来描述问题的算法。
算法数据结构是程序的两个重要方面。
算法是问题求解过程的精确描述,一个算法由有限条可完全机械地执行的、有确定结果的指令组成。
指令正确地描述了要完成的任务和它们被执行的顺序。
计算机按算法指令所描述的顺序执行算法的指令能在有限的步骤内终止,或终止于给出问题的解,或终止于指出问题对此输入数据无解。
通常求解一个问题可能会有多种算法可供选择,选择的主要标准是算法的正确性和可靠性,简单性和易理解性。
其次是算法所需要的存储空间少和执行更快等。
算法设计是一件非常困难的工作,常用的算法设计方法主要有迭代法、穷举搜索法、递推法、递归法、贪婪法、回溯法、分治法、动态规划法等。
一、迭代法迭代法是用于求方程或方程组近似根的一种常用的算法设计方法。
设方程为f(x)=0,用某种数学方法导出等价的形式x=g(x),然后按以下步骤执行:(1)选一个方程的近似根,赋给变量x0;(2)将x0的值保存于变量x1,然后计算g(x1),并将结果存于变量x0;(3)当x0与x1的差的绝对值还大于指定的精度要求时,重复步骤(2)的计算。
若方程有根,并且用上述方法计算出来的近似根序列收敛,则按上述方法求得的x0就认为是方程的根。
上述算法用C程序的形式表示为:【算法】迭代法求方程的根{ x0=初始近似根;do {x1=x0;x0=g(x1); /*按特定的方程计算新的近似根*/} while ( fabs(x0-x1)>Epsilon);prin tf(“方程的近似根是%f\n”,x0);}具体使用迭代法求根时应注意以下两种可能发生的情况:(1)如果方程无解,算法求出的近似根序列就不会收敛,迭代过程会变成死循环,因此在使用迭代算法前应先考察方程是否有解,并在程序中对迭代的次数给予限制;(2)方程虽然有解,但迭代公式选择不当,或迭代的初始近似根选择不合理,也会导致迭代失败。
acm竞赛知识点
ACM竞赛知识点简介ACM竞赛是指由国际大学生程序设计竞赛(ACM-ICPC)组织的一系列编程比赛。
ACM竞赛旨在培养学生的计算机科学和编程能力,提高解决实际问题的能力和团队合作精神。
本文将介绍ACM竞赛的基本知识点和技巧,帮助读者更好地了解和参与这一竞赛。
知识点1. 数据结构在ACM竞赛中,数据结构是解决问题的关键。
以下是一些常用的数据结构:•数组:用于存储一组相同类型的数据。
•链表:用于存储和操作具有相同数据类型的元素。
•栈:一种后进先出(LIFO)的数据结构。
•队列:一种先进先出(FIFO)的数据结构。
•树:一种非线性的数据结构,由节点和边组成。
•图:一种由节点和边组成的数据结构,用于表示各种关系。
2. 算法ACM竞赛中常用的算法包括:•排序算法:如快速排序、归并排序、堆排序等,用于将数据按照一定的规则进行排序。
•查找算法:如二分查找、哈希表等,用于在数据中查找指定的元素。
•图算法:如深度优先搜索(DFS)、广度优先搜索(BFS)、最短路径算法等,用于解决图相关的问题。
•动态规划:一种将复杂问题分解为简单子问题的方法,用于解决多阶段决策问题。
•贪心算法:一种每一步都选择当前最优解的方法,用于解决优化问题。
3. 数学数学在ACM竞赛中扮演着重要的角色。
以下是一些常用的数学知识点:•组合数学:包括排列组合、二项式定理、卡特兰数等,用于计算对象的排列和组合方式。
•数论:包括素数、最大公约数、最小公倍数等,用于解决与整数相关的问题。
•概率与统计:包括概率分布、统计推断等,用于分析和预测事件发生的概率。
•矩阵与线性代数:用于解决与矩阵和线性方程组相关的问题。
4. 字符串处理在ACM竞赛中,字符串处理是常见的问题之一。
以下是一些常用的字符串处理技巧:•字符串匹配:如KMP算法、Boyer-Moore算法等,用于在一个字符串中查找另一个字符串。
•字符串排序:如字典序排序、后缀数组等,用于对字符串进行排序。
树习题解答
数据结构——树习题解答1、单词查找树(word.pas)【问题描述】在进行文法分析的时候,通常需要检测一个单词是否在我们的单词列表中。
为了提高查找和定位的速度,通常都画出与单词列表所对应的单词查找树,其特点如下:(1)根节点不包含字母,除根街店为每一个节点都包含一个大写英文字母;(2)从根节点到某一节点,路径上经过的字母依次连起来所构成的字母序列,称为该结点对应的单词。
单词列表中的每个单词,都是该单词查找树某个节点所对应的单词;(3)在满足上述条件下,该单词查找树的节点数最少。
要求:对一个确定的单词列表,请统计对应的单词查找树的结点数(包括根节点).输入:输入文件名为word.in,该文件为一个单词列表,每行仅包含一个单词和一个换行/回车符。
每个单词仅由大写字母组成,长度不超过63个字符。
文件总长度不超过32K,至少有一行数据。
输出:输出文件名为word.out,该文件仅包含一个整数,该整数为单词列表对应的单词查找树的结点数。
【样例输入】AANASPASASCASCIIBASBASIC【样例输出】13【题解】首先要对建树的过程有一个了解。
对于当前被处理的单词和当前树:在根节点的子节点中找单词的为第一位字母,若存在则进而在该节点的子节点中寻找第二位……,如此直到单词结束,既不需要在该书中添加节点;若单词的第n个字母不能找到,即将单词的第n个字母及其后的字母依次加入单词查找树中。
但本题只是问你结点总数,而非建树方案,且有32K大小的单词文件,所以应该考虑能不能通过不建树就直接算出结点数。
为了说明问题本质,我们定义单词相对于另一个单词的差:设单词1的长度为L,且与单词2从第N位开始不一致,则定义单词1相对于单词2的差为L-N+1,这是描述单词相似程度的量。
可见,将一个单词加入单词树的时候,须加入的节点数等于该单词树中已有的单词的差得最小值。
单词的字典顺序排列后的序列则具有类似的特性,即在一个字典顺序序列中,第m个单词相对于第m-1个单词的差必定是它对于前m-1个单词的差中最小的。
acm基础试题及答案
acm基础试题及答案1. 题目:给定一个整数数组,请找出数组中第二大的数。
答案:我们可以使用排序的方法,将数组从小到大排序,然后数组中的倒数第二个数就是第二大的数。
或者使用一次遍历的方法,首先初始化两个变量,一个用来存储最大值,一个用来存储第二大的值。
遍历数组,每次比较当前元素与最大值,如果当前元素大于最大值,则更新第二大的值为最大值,并将当前元素赋给最大值;如果当前元素小于最大值但大于第二大的值,则更新第二大的值。
2. 题目:实现一个函数,计算一个字符串中字符出现的次数。
答案:可以使用哈希表来实现,遍历字符串中的每个字符,将其作为键值对存储在哈希表中,键是字符,值是该字符出现的次数。
遍历结束后,哈希表中存储的就是每个字符出现的次数。
3. 题目:给定一个链表,删除链表的倒数第n个节点,并且返回新的链表头节点。
答案:可以使用双指针的方法,首先初始化两个指针,都指向链表的头节点。
然后移动第一个指针,移动n步,此时第一个指针指向倒数第n个节点的前一个节点。
接着同时移动两个指针,直到第一个指针到达链表的末尾,此时第二个指针指向的节点就是需要删除的节点的前一个节点。
然后更新第二个指针的next指针,使其指向第二个指针的next节点的next节点,最后返回链表的头节点。
4. 题目:编写一个函数,判断一个整数是否是回文数。
回文数是指正序和倒序读都一样的数。
答案:首先将整数转换为字符串,然后使用双指针的方法,一个指针从字符串的开始位置,一个指针从字符串的结束位置,向中间移动。
如果两个指针指向的字符不相等,则该整数不是回文数。
如果遍历结束后没有发现不相等的字符,则该整数是回文数。
5. 题目:给定一个字符串,找出其中不含有重复字符的最长子串的长度。
答案:可以使用滑动窗口的方法,维护一个哈希表记录窗口内字符的出现情况,以及一个变量记录不含有重复字符的最长子串的长度。
遍历字符串,每次移动窗口的右端点,如果当前字符不在窗口内,则更新最长子串的长度,并将字符添加到哈希表中。
acm数论知识点总结
acm数论知识点总结1. 整除与余数整除是数论中最基本的概念之一。
如果一个整数a可以被另一个整数b整除,那么我们说b是a的一个因子,记作b|a。
如果a不能被b整除,记作b∣a。
另外,如果a除以b得到的商为q,余数为r,那么我们有a=bq+r,并且0≤r<|b|。
这里的余数r可以用来求解问题,比如判断一个数是奇数还是偶数;或者用来求解同余方程。
2. 最大公约数和最小公倍数两个整数a和b的最大公约数(Greatest Common Divisor,GCD)是能够整除a和b的最大的整数。
通常记作gcd(a, b)。
最小公倍数(Least Common Multiple,LCM)是能够被a和b整除的最小的整数。
通常记作lcm(a, b)。
最大公约数和最小公倍数可以用辗转相除法快速求解,而且它们有一些常见的性质,比如gcd(a, b)⋅lcm(a, b)=a⋅b。
3. 素数素数是指只能被1和自身整除的正整数。
素数在数论中是非常重要的,它们有许多特殊的性质。
比如任意一个整数都可以分解成若干个素数的乘积。
素数在ACM竞赛中常用于判断数字的性质,或者用于设计算法。
4. 同余同余是数论中一个重要的概念,如果两个整数a和b除以一个正整数m得到的余数相同,那么我们就说a同余b模m,记作a≡b(mod m)。
同余关系具有传递性和对称性,满足一些特殊的性质。
同余关系可以用来求解很多问题,比如求解同余方程、构造递归关系等。
5. 奇数和偶数奇数是最基本的整数,它们可以被2整除;偶数是能够被2整除的整数。
奇数和偶数在一些问题中有特殊的性质,比如奇数乘以奇数得到的是奇数,奇数加偶数得到的是奇数等。
6. 欧拉定理欧拉定理是数论中一个著名的定理,它为解决同余方程提供了一个重要的工具。
欧拉定理表明,如果正整数a和m互质(即gcd(a, m)=1),那么a的欧拉函数值为φ(m),则a^φ(m)≡1(mod m)。
欧拉定理在RSA密码算法中有重要应用。
ACM竞赛所用数据结构
红黑树的使用
其插入、删除、修改的算法复杂度均为n*log(n)。 具体实现也比较复杂,可以参考相关数据结构书籍, 在比赛中一般也使用STL. 集合<set>
– 定义:set<double,greater<int>> t;multiset<int> t(a.begin(),a.end(),cmp); – 插入:tree.insert(val); multiset返回bool; set返回pair其 中.second表示是否插入成功, .first表示新元素或现存同值元 素的位置。 – 改变:该类型内容是只读的,不能改变 – 查找:tree.find(val);返回值为val的第一个元素的迭代器; tree.lower_bound(val); 返回第一个大于等于val的元素位置 – 删除:tree.erase(tree.begin());
后缀数组
附件中相关资料
关于后缀数组
字符串处理当中,后缀树和后缀数组都是 非常有力的工具,其中后缀树大家了解得 比较多,关于后缀数组则很少见于国内的 资料。其实后缀数组是后缀树的一个非常 精巧的替代品,它比后缀树容易编程实现, 能够实现后缀树的很多功能而时间复杂度 也不太逊色,并且,它比后缀树所占用的 空间小很多。可以说,在ACM比赛中中后 缀数组比后缀树要更为实用。
树
树的一般表示法
数组父亲表示法 儿子节点表示法(用指针构建多叉树)
比赛的时候常用vector来构造
左儿子右兄弟表示法
哈夫曼树
哈夫曼树又称最优树(二叉树),是一类 带权路径最短的树。构造这种树的算法最 早是由哈夫曼(Huffman)1952年提出,这种 树在信息检索中很有用。 定义:
(完整版)《树》知识点总结
(完整版)《树》知识点总结本文档总结了关于"树"的知识点,旨在帮助读者更好地理解和运用这一数据结构。
1. 什么是树树是一种层次结构的数据结构,由节点和边组成。
它起始于一个根节点,每个节点可以有零个或多个子节点,子节点之间通过边连接起来。
2. 树的基本术语- 节点(Node): 树中的基本单元,存储数据和指向其子节点的指针。
节点(Node): 树中的基本单元,存储数据和指向其子节点的指针。
- 根节点(Root): 树的顶层节点,没有父节点。
根节点(Root): 树的顶层节点,没有父节点。
- 子节点(Child Node): 一个节点的直接后继,由父节点指向。
子节点(Child Node): 一个节点的直接后继,由父节点指向。
- 叶节点(Leaf Node): 没有子节点的节点。
叶节点(Leaf Node): 没有子节点的节点。
- 父节点(Parent Node): 一个节点的直接前驱,指向该节点的节点。
父节点(Parent Node): 一个节点的直接前驱,指向该节点的节点。
- 兄弟节点(Sibling Node): 具有同一父节点的节点。
兄弟节点(Sibling Node): 具有同一父节点的节点。
3. 树的常见类型3.1 二叉树(Binary Tree)二叉树是一种特殊的树结构,每个节点最多有两个子节点,分别称为左子节点和右子节点。
3.2 二叉搜索树(Binary Search Tree)二叉搜索树是一种二叉树,具有以下特性:- 每个节点的值大于其左子树中任意节点的值。
- 每个节点的值小于其右子树中任意节点的值。
- 左子树和右子树都是二叉搜索树。
3.3 平衡二叉树(Balanced Binary Tree)平衡二叉树是一种特殊的二叉搜索树,具有以下特性:- 左子树和右子树的高度差不超过1。
4. 树的遍历方式树的遍历方式分为三种:- 前序遍历(Preorder Traversal): 先访问根节点,然后递归地遍历左子树和右子树。
acm编程例题 参考答案
acm编程例题参考答案ACM编程例题参考答案ACM(Advanced Computer Mathematics)是一种面向计算机科学与技术的竞赛形式,旨在提高参与者的编程技能和解决问题的能力。
ACM编程例题是指在ACM竞赛中出现的一系列编程题目,这些题目涵盖了各种算法和数据结构的应用。
本文将给出一些ACM编程例题的参考答案,希望能够帮助读者更好地理解和掌握这些题目的解法。
一、题目一:最大公约数题目描述:给定两个正整数a和b,求它们的最大公约数。
解题思路:最大公约数可以通过欧几里得算法来求解。
该算法的基本思想是,两个正整数的最大公约数等于其中较小的数和两数之差的最大公约数。
具体的实现可以使用递归或循环的方式。
代码示例:```c++int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);}```二、题目二:素数判断题目描述:给定一个正整数n,判断它是否为素数。
解题思路:素数是只能被1和自身整除的正整数。
判断一个数是否为素数可以使用试除法,即从2开始,依次判断n是否能被2到sqrt(n)之间的数整除。
如果存在能整除n的数,则n不是素数;否则,n是素数。
代码示例:```c++bool isPrime(int n) {if (n <= 1) {return false;}for (int i = 2; i * i <= n; i++) {if (n % i == 0) {return false;}}return true;}```三、题目三:字符串反转题目描述:给定一个字符串s,将其反转后输出。
解题思路:字符串反转可以通过将字符串的首尾字符依次交换来实现。
可以使用双指针的方式,一个指针指向字符串的首字符,另一个指针指向字符串的尾字符,然后交换两个指针所指向的字符,并向中间移动,直到两个指针相遇。
代码示例:```c++void reverseString(string& s) {int left = 0;int right = s.length() - 1;while (left < right) {swap(s[left], s[right]);left++;right--;}}```四、题目四:二分查找题目描述:给定一个有序数组和一个目标值,使用二分查找算法在数组中找到目标值的索引,如果目标值不存在,则返回-1。
ACM基础算法入门
辗转相除法
扩展欧几里得
双六 一个双六上面有向前向后无限延续的格子,每个格子都写有整数。其中0号格子 是起点,1号格子是终点。而骰子上只有 a , b , -a , -b 四个整数,所以根据 a 和 b 的值的不同,有可能无法到达终点。 格子如下: …… -4 -3 -2 -1 0 1 2 3 4 …… 掷出四个整数各多少次可以到达终点?输出任意一组解。 1<= a , b <=10^9
0 1 0 0 1
解题过程
本题是简单的搜索问题,采用深度优先 遍历可以解决,根据题目要求,假设从 任意一点值为'1'的出发,将这点的坐标 上下左右全部用'0'替换,1次DFS后与初 始动这个'1'连接的'1'全部被替换成'0', 因此,直到图中不再存在'1'为至,总共 进行的DFS的次数就是最后的结果咯!那 么,根据题目要求,有4个方向,时间复 杂度为O(4*n*m)。
例题:
水池数目 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池, 假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在, 你的任务来了,请用计算机算出该地图中共有几个水池。 输入m行每行输入n个数,表示此处有水还是没水 (1表示此处是水池,0表示此处是地面) 0<m<100 0<n<100 输入: 34 1000 0011 1110 输出: 2 输入: 55 1111 0010 0000 1110 0011 输出: 3
把各区间按照a从小到大顺序。如果区间1的起点不是s, 则无解,即[s,t]无法被完全覆盖(因为其他区间的起点更大, 不可能覆盖到s点),否则选择起点在s的最长区间。选择此 区间[ai,bi]后,新的起点应该被设置为bi,并且忽略所有区间在 bi之前的部分,就像预处理一样。虽然贪心策略比上面的题 复杂,但是仍然只需要一次扫描。如下图5所示。s为当前有 效起点(此前部分已被覆盖),则应该选择区间2。
树的等价定义及其证明
树的等价定义及其证明在数据结构中,树是一种重要的抽象数据类型,它以树形结构存储数据,其特点是每个节点(除了根节点外)最多只有一个父节点,而每个节点可以有若干个子节点,且节点之间的关系是单向的。
树的结构具有许多有用的性质,它可以用于组织文件、储存数据等多种用途。
给出树的一般定义:树是一个非空的有穷集T,其中有一个特定的元素称为根节点,T中的其他元素被划分为m个互不相交的有限的集合T1,T2,…,Tm,其中每个Ti(i=1,2,…,m)也是一棵树,称为根的子树。
给出树的一些等价定义:1. 一棵树是一个非空集合T,其中有一个特定元素称为根,及m 个互不相交的有限集合,称为根的子树,其中每个子树都可以看成是根的子树;2. 一棵树可以看成是由一组节点构成的有序集合,其中节点可以看成是树中各个元素的延伸,而节点之间由某种联系构成树状结构;3. 一棵树由其根节点以及其各个子树的集合构成,其中其根节点可以看成是树的核心,由其统领着整棵树;4. 一棵树可以看成是一个连接节点的无向图,其中节点之间的关系是单向的,以根节点为起点到达每个节点的路径唯一,无回路;5. 一棵树是一个层次化的结构,其中根节点位于第一层,以下每层逐级延伸,并且每层有若干子节点,形成一个多叉树结构。
以上就是树的一般定义以及它的等价定义,那么我们再来看看它的证明,就是如何证明树的一般定义以及它的等价定义是一致的。
首先,我们以树形图的形式来说明:对于给定的树T,由根节点可以得知其子节点,因此可以构建一幅树形图来表示树T,其中根节点表示为第0层,其子节点为第1层,以此类推,将树T表示为一棵多叉树,其中每个节点有若干子节点,子节点与父节点具有联系,形成一个树,这个根据树形图构造的树就是给定树T的一种表达形式,也是等价的。
其次,我们以关系图的形式来说明:我们可以把树T看成一组节点的无向图,其中每个节点都有一个父节点,节点之间的关系是单向的,而且每个节点之间的路径都是唯一的,每个节点的子节点正是根据其父节点的关系来构造的,如此就形成了一棵树,这个树便是给定树T的另一种表达形式,也是等价的。
国家集训队2009论文集分治算法在树的路径问
1
IOI2009 中国国家集训队论文
长沙市雅礼中学 漆子超
【目录】
【序言】........................................................................................................................ 3 【正文】........................................................................................................................ 4 一.树的分治算法.................................................................................................... 4 基于点的分治:.............................................................................................. 4 基于边的分治:.............................................................................................. 4 效率分析:...................................................................................................... 5 【例 1】树中点对统计................................................................................... 8 算法分析................................................................................................... 8 【例 2】Free Tour 2 ...................................................................................... 10 算法分析................................................................................................. 10 【本节小结】................................................................................................ 13 二.树的路径剖分算法:................................................................................... 14 【例 3】Query On a Tree.............................................................................. 14 算法分析................................................................................................. 14 引入路径剖分......................................................................................... 14 轻重边路径剖分..................................................................................... 15 【例 4】黑白树 ........................................................................................... 17 算法分析................................................................................................. 17 【小结】........................................................................................................ 18 路径剖分与树的分治的联系:.................................................................... 19 【例 5】Query On a Tree Ⅳ ........................................................................ 20 算法分析................................................................................................. 20 【本节小结】................................................................................................ 23 三.树的分治的进一步探讨:........................................................................... 24 如何改进基于边的分治的时间复杂度........................................................ 24 使用基于边的分治解决【例 2】................................................................. 26 使用基于边的分治解决【例 5】................................................................. 27 四.全文总结....................................................................................................... 28 【参考文献】.............................................................................................................. 29 【感谢】...................................................................................................................... 29 【附录】...................................................................................................................... 29
acm竞赛相关知识点总结
acm竞赛相关知识点总结一、算法设计算法设计是 ACM 竞赛中最为重要的一个环节。
合适的算法可以大大提高解题效率,而不合适的算法可能导致题目无法在规定时间内完成。
常见的算法设计包括贪心算法、分治算法、动态规划、搜索算法等。
在实际比赛中,常用的算法有:1. 贪心算法贪心算法是一种在每一步选择中都采取当前状态下的最优解,从而希望全局得到最优解的算法。
贪心算法的特点是简单、高效,但不能保证获得全局最优解。
2. 分治算法分治算法是将问题分解成若干个小规模的子问题,解决子问题后再将结果合并起来,得到原问题的解。
常见的分治算法包括归并排序、快速排序等。
3. 动态规划动态规划是一种将问题分解成若干个重叠子问题,通过存储中间结果避免重复计算,从而提高解题效率的算法。
动态规划常用于解决最优化问题,如最长递增子序列、最大子数组和等。
4. 搜索算法搜索算法分为深度优先搜索(DFS)和广度优先搜索(BFS)。
DFS 是一种将问题转化成树状结构进行搜索的算法,BFS 则是一种层次遍历的方法。
搜索算法通常用于解决图论问题、路径搜索等。
二、数据结构数据结构在 ACM 竞赛中也扮演着非常重要的角色。
合适的数据结构可以大大简化问题的解决过程,提高解题效率。
常见的数据结构包括数组、链表、栈、队列、树、图等。
在ACM 竞赛中,常用的数据结构有:1. 数组数组是存储相同类型数据的集合,可以通过下标快速访问元素。
在 ACM 竞赛中,数组常用于存储数据、处理统计信息等。
2. 栈栈是一种先进后出的数据结构,在 ACM 竞赛中常用于表达式求值、括号匹配等。
3. 队列队列是一种先进先出的数据结构,常用于 BFS 搜索、模拟等。
4. 树树是一种重要的数据结构,在 ACM 竞赛中常用于表示层次结构、存储排序信息等。
常见的树结构包括二叉树、堆、并查集等。
5. 图图是一种用于表示网络结构的数据结构,常用于解决最短路径、最小生成树等问题。
三、图论图论是 ACM 竞赛中的一个重要领域,涉及了大量的算法和数据结构。
树
生成树的性质
设 G V , E 为连通图, V n, E m, (1) G至少有一棵生成树, (2) m n 1, (3) 设 T 是 G 的生成树, T ' 是 T 的余树,
则 T '中有 m n 1条边。 (4) 设 T 是 G 的生成树, T ' 是 T 的余树,
又由(1) m n 1 ,代入上式,解得 k 2 ,
即 T 至少2片叶。
例题
画出所有的6个顶点的非同构的树。 解:所要画的树有6个顶点,则边数为5,因此 6个顶点的度数之和为10,可以产生以下五 种 度数序列:
(1) 1 1 1 1 1 5
T1
(2) 1 1 1 1 2 4
(3) 1 1 1 1 3 3
注意: (1) 生成树不唯一,
(2) 余树不一定是树。
(3)
(3)是(2)的余树。
生成树存在条件
定理:无向图G具有生成树当且仅当G是连通图 证明:
必要性 显然 充分性,如果G无回路,则G本身就是它的生成树,如G 有回路,则在回路上任取一条边并去掉后仍是连通的, 如G仍有回路,则继续在该回路上去掉一条边,直到图 中无回路为止,此时该图就是G的一棵生成树
树的性质
(1) 树中顶点数与边数的关系: n m 1 。
(2) 非平凡树至少2片树叶。
证明: 设 T V , E 为 n 阶非平凡树,
设 T 有 k 片树叶,则有 (n k) 个顶点度数大于等
n
于2, 由握手定理, 2m d (vi ) k 2(n k ) i 1
T2
(4) 1 1 1 2 2 3
T3
(5)1 1 2 2 2 2
树与生成树
定理1 T是棵完全m叉树, 有t个叶结点, i个分支结点, 则(m-1)i=t -1 . 证明:T的所有结点的出度总和为 mi. 入度总和(i-1)+t. 故 mi=i-1+t 所以(m-1)i=t-1
七. m叉有序树转化成二叉树 因为二叉树便于存贮, 也便于处理, 所以通常可以将多叉 树化成二叉树.方法是: 1.每个结点保留左儿子结点, 剪掉右边其分支. 被剪掉 的结点如下处理(重新嫁接). 2.同一个层次的结点, 从左到右依次画出(被剪掉的结 点 嫁接到它的哥哥结点上).
先将权按照升序排序设为w为儿子结点构造它们的父结点且其权为再与其余权一起排序再从此队列中取出前面两个权值为儿子结点同的方法构造它们的父结点
8-9 树与生成树
树是一种特殊的图, 它是图论中重要的概念之一, 它有 着广泛的应用.在计算机科学中有如判定树、语法树、分 类树、搜索树、目录树等等. 一.树 (Tree) (a) 1.树的定义:一个连通无回路的 无向图T,称之为树. 如(a) 2.叶结点:度数为1的结点, 称为叶结点. (b) 3.分支结点(内结点):度数大于1的结点. 4.森林:一个无向图的每个连通分支都是树.如(b)
⑷ T连通的,且每条边都是割边. ⑸ T连通的且m=n-1. ⑷⑸:关于点数用归纳法证明。 当n=1或2时,T是平凡图或K2,显然有m=n-1。 假设nk时结论成立,往证n=k+1时成立。 当n=k+1时。取T的一条边e,由⑷,e是割边, 所以T-e有两个分支T1和T2, 因为|V(T1)|k, |V(T2)|k, 所以,由归纳假设,有 |E(T1)|=|V(T1)|-1, |E(T2)|=|V(T2)|-1 故m=|E(T1)|+|E(T2)|+1 =|V(T1)|-1+ |V(T2)|-1+1 =n-1。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int fix_mfset( MFSet &S, int i){
if(i<1||i>S.n) return -1;
for(j=i;S.nodes[j].parent>0;j=S.nodes[j].parent);
for(k=i;k!=j;k=t){
t=S.nodes[k].parent;
当所有的m个关系处理完后,剩下的这些非空子 集即为S的R等价类。
6.5 树与等价问题
划分等价类需对集合进行的三个基本操作: 构造只含一个元素的集合 判定某个元素所在的子集 合并两个互不相交的集合
约定: 利用树型结构表示集合,每个节点表示集合的元
素 根节点的成员兼作子集的名称
6.5 树与等价问题
}
return OK; }// mix_mfset
深度不超过┗ log2n+1 ┛
6.5 树与等价问题
一个实例
假设集合S={x|1≤x ≤n是正整数},R是S上的 一个等价关系。
R={(1,2),(3,4),(5,6),(7,8),(1,3),(5,7),(1,5),…} 求S的等价类
1 2 3 4 5 6 7 8…n
if( S.nodes[i].parent>S.nodes[j].parent){
S.nodes[j].parent+=S.nodes[i].parent;
S.nodes[i].parent=j;
}else{
S.nodes[i].parent+=S.nodes[j].parent;
S.nodes[j].parent=i;
n
1 2 3 ... n
3
3
2
2 ... 2
1
1
16.5 树与等价问题改进“并”操作的算法,令成员少的子集树根节点指向成员多的子集的 根;修改存储结构—令根节点的parent与存储子集中所含成员数目的负
值St。atus mix_mfset( MFSet &S, int i, int j){
if(i<1||i>S.n||j<1||j>S.n) return ERROR;
-1 -1 -1 -1 -1 -1 -1 -1
-1
处理(1,2),(3,4),(5,6),(7,8)之后
1 2 3 4 5 6 7 8…n
-2 1 -2 3 -2 5 -2 7
-1
6.5 树与等价问题
一个实例
假设集合S={x|1≤x ≤n是正整数},R是S上的 一个等价关系。
R={(1,2),(3,4),(5,6),(7,8),(1,3),(5,7),(1,5),…} 求S的等价类
}// merge_mfset
O( 1)
6.5 树与等价问题
上述实现对于这样的例子:
假设n个集合S1,S2,…,Sn, 每个子集只有一个元素Si={i}, 用n棵只有一个根节点的树表示,做n-1次并操作后, 最后得到的集合的深度为n,加上每次进行查找成员 “1”所在子集的操作,全部操作时间是O(n2)。
(x,y ∈ S)的等价偶对确定了等价关系R,求S 的划分。
6.5 树与等价问题
确定等价类的算法:
令S中每个元素各自形成一个只含单个成员的子集, 记作S1,S2,…,Sn
重复读入m个关系(偶对),对每个读入的偶对 (x,y),判定x和y所属的子集,若这两个子集不相等, 则合并它们并取代这两个子集
6.5 树与等价问题
离散数学中的概念: 集合S上的关系R定义为SxS的一个子集。 等价关系是具有自反、传递、对称的关系。 若R是S上的等价关系,由R可以产生这个集合S的
一个唯一的划分S1,S2…,这些集合互不相交,其并 为S,分别属于不同的等价类。
6.5 树与等价问题
确定等价类的问题 假设集合S有n个元素,已知m个形如(x,y)
}// find_mfset
O( d) d—树的深度
Status merge_mfset( MFSet &s, int i, int j){ //集合的并 if( i<1||i>S.n||j<1||j>S.n) return ERROR; S.nodes[i].parent=j; return OK;
1 2 3 4 5 6 7 8…n
-4 1 1 3 -4 5 5 7
-1
处理(1,5)之后
1 2 3 4 5 6 7 8…n
-8 1 1 3 1 5 5 7
-1
6.5 树与等价问题
改进查找子集算法,增加“压缩路径”功能。当所查元素i不 在树的第二层时,在算法中增加一个“压缩路径”的功能, 即将所有从根到元素i路径上的元素都变成树根的孩子。
1 2 3 4 5 6 7 8…n
-2 1 -2 3 -2 5 -2 7
-1
处理(1,3),(5,7)之后
1 2 3 4 5 6 7 8…n
-4 1 1 3 -4 5 5 7
-1
6.5 树与等价问题
一个实例
假设集合S={x|1≤x ≤n是正整数},R是S上的 一个等价关系。
R={(1,2),(3,4),(5,6),(7,8),(1,3),(5,7),(1,5),…} 求S的等价类
集合的表示 用代树表Ti表每示个每元个素子,集每S棵i,树森的林根F节表点示同集时合S用,来每表个示节子点
集Si
两种关键的基本操作:查找某个元素是否属于某个 集合,合并两个集合。采用何种树、森林的存储 方式可以有效地实现这些基本操作?
集合的并:将一子树的根指向另一子树的根即可 是否属于集合:从该节点出发,逐级查找父节点到
S.nodes[k].parent=j; 经过这些改进后,划分等价类的时间
}
复杂度为O(nα(n)),其中α(n)≤4
return j;
}// fix_mfset
根节点为止。
6.5 树与等价问题
typedef PTree MFSet;
int find_mfset( MFSet S, int i){ //查找i所属子集 if( i<1 || i>S.n) return -1; for( j=i; S.nodes[j].parent>0; j=S.nodes[j].parent); return j;