那个叫二叉树啊
树是一种重要的非线性数据结构,直观地看,它是数据元素(在树中称为结点)按分支关系组织起来的结构,很象自然界中的树那样。树结构在客观世界中广泛存在,如人类社会的族谱和各种社会组织机构都可用树形象表示。树在计算机领域中也得到广泛应用,如在编译源程序如下时,可用树表示源源程序如下的语法结构。又如在数据库系统中,树型结构也是信息的重要组织形式之一。一切具有层次关系的问题都可用树来描述。
一、树的概述
树结构的特点是:它的每一个结点都可以有不止一个直接后继,除根结点外的所有结点都有且只有一个直接前趋。以下具体地给出树的定义及树的数据结构表示。
(一)树的定义
树是由一个或多个结点组成的有限集合,其中:
⒈必有一个特定的称为根(ROOT)的结点;
⒉剩下的结点被分成n>=0个互不相交的集合T1、T2、Tn,而且,
这些集合的每一个又都是树。树T1、T2、Tn被称作根的子树(Subtree)。
树的递归定义如下:(1)至少有一个结点(称为根)(2)其它是互不相交的子树
1树的度——也即是宽度,简单地说,就是结点的分支数。以组成该树各结点中最大的度作为该树的度,如上图的树,其度为3;树中度为零的结点称为叶结点或终端结点。树中度不为零的结点称为分枝结点或非终端结点。除根结点外的分枝结点统称为内部结点。
2树的深度——组成该树各结点的最大层次,如上图,其深度为4;
3森林——指若干棵互不相交的树的集合,如上图,去掉根结点A,其原来的二棵子树T1、T2、T3的集合就为森林;
4有序树——指树中同层结点从左到右有次序排列,它们之间的次序不能互换,这样的树称为有序树,否则称为无序树。
5树的表示
树的表示方法有许多,常用的方法是用括号:先将根结点放入一对圆括号中,然后把它的子树由左至右的顺序放入括号中,而对子树也采用同样的方法处理;同层子树与它的根结点用圆括号括起来,同层子树之间用逗号隔开,最后用闭括号括起来。如上图可写成如下形式:
(A(B(E(K,L),F),C(G),D(H(M),I,J)))
5
2
二叉树
1二叉树的基本形态:
二叉树也是递归定义的,其结点有左右子树之分,逻辑上二叉树有五种基本形态:
(1)空二叉树——(a);
(2)只有一个根结点的二叉树——(b);
(3)右子树为空的二叉树——(c);
(4)左子树为空的二叉树——(d);
(5)完全二叉树——(e)
注意:尽管二叉树与树有许多相似之处,但二叉树不是树的特殊情形。
这种树状思维导图可以用思维导图软件MindManager来做
树状思维导图属于思维导图中较为简单的类型。我们在日常的学习、工作中,可能不知不觉中已经绘制过树状思维导图。其特点是,分支主题大多数是平行或包含的关系,多用于枚举、整体与部分等思维导图的绘制。
如果您还是不清楚树状思维导图要怎么画,建议直接使用MindManager思维导图软件的树形思维导图模板。即使是新手,也能通过套用MindManager的树形模板轻松完成树状思维导图的绘制。
一、使用预设模板
那么,怎么使用MindManager的树状思维导图模板?
如图1所示,打开MindManager的新建页面,即可在其空白模板类别中找到“树形导图”,通过“树形导图”即可创建树状思维导图。
图1:MindManager树状思维导图模板
二、选取合适的格式
在使用“树形导图”模板时,如图2所示,打开MindManager的设计菜单,我们既可以选取经典的树形导图样式,即单向向下延伸的样式。
图2:竖向树状思维导图
也可以选取如图3所示的拆分树样式,相对而言,拆分树更适合用于副主题较多的思维导图,而经典的树形导图样式更适合简单的、有逻辑顺序要求的思维导图。
图3:拆分树思维导图
三、创建主题并填充分支
在本文中,我们会以“旅行行李准备清单”为例,制作树状思维导图。由于这类型的思维导图涉及到较多的副主题(即行李类型),因此会选取“拆分树”的样式。
如图4所示,首先创建第一层分支,即行李的类型,分为洗漱用品、衣物等六类行李。
图4:创建行李分类
接着,如图5所示,再分别细化每一种行李类型,如洗漱用品可细化为毛巾、牙膏牙刷;化妆品可细化为口红、粉底液等。
图5:填充分类分支
四、格式化导图
完成了树形思维导图的绘制后,如图6所示,打开MindManager的设计菜单,为思维导图选择合适的主题样式。由于本例中的导图分支较多,因此我们选取了一个线条更细的样式。
图6:设计功能
我最近也在研究这个,你可以从网上搜treedp,这里我给你传一份吧
加分二叉树
问题描述
设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号。每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一个加分,任一棵子树subtree(也包含tree本身)的加分计算方法如下:
subtree的左子树的加分× subtree的右子树的加分+subtree的根的分数
若某个子树为空,规定其加分为1,叶子的加分就是叶节点本身的分数。不考虑它的空子树。
试求一棵符合中序遍历为(1,2,3,…,n)且加分最高的二叉树tree。要求输出;
(1)tree的最高加分
(2)tree的前序遍历
[分析]很显然,本题适合用动态规划来解。如果用数组value[i,j]表示从节点i到节点j所组成的二叉树的最大加分,则动态方程可以表示如下:
value[i,j]=max{value[i,i]+value[i+1,j],value[i+1,i+1]+value[i,i]value[i+2,j], value[i+2,i+2]+value[i,i+1]value[i+3,j],…,value[j-1,j-1]+value[i,j-2]value[j,j], value[j,j]+value[i,j-1]}
题目还要求输出最大加分树的前序遍历序列,因此必须在计算过程中记下从节点i到节点j所组成的最大加分二叉树的根节点,用数组root[i,j]表示
Ural 1018 二苹果树
题目
有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点)
这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1。
我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4个树枝的树
2 5
\ /
3 4
\ /
1
现在这颗树枝条太多了,需要剪枝。但是一些树枝上长有苹果。
给定需要保留的树枝数量,求出最多能留住多少苹果。
输入格式
第1行2个数,N和Q(1<=Q<= N,1<N<=100)。
N表示树的结点数,Q表示要保留的树枝数量。接下来N-1行描述树枝的信息。
每行3个整数,前两个是它连接的结点的编号。第3个数是这根树枝上苹果的数量。
每根树枝上的苹果不超过30000个。
输出格式
一个数,最多能留住的苹果的数量。
解析:因为题目一给出就是二叉的,所以很容易就可以写出方程:
a(I,j):=max(a(ileft,k)+a(iright,j-k)),0<=k<=j
源程序代码:
由于比较简单便不给完全的代码了。
Function treedp(x,y:longint):longint;
Var I,j,k:longint;
Begin
J:=0;
For I:=0 to y do
begin
k:=treedp(b[x]l,I)+treedp(b[x]r,y-I);
if k>j then j:=k;
end;
treedp:=j;
End;
选课
[问题描述]
在大学里每个学生,为了达到一定的学分,必须从很多课程里选择一些课程来学习,在课程里有些课程必须在某些课程之前学习,如高等数学总是在其它课程之前学习。现在有N门功课,每门课有个学分,每门课有一门或没有直接先修课(若课程a是课程b的先修课即只有学完了课程a,才能学习课程b)。一个学生要从这些课程里选择M门课程学习,问他能获得的最大学分是多少?
输入:
第一行有两个整数N,M用空格隔开。(1<=N<=200,1<=M<=150)
接下来的N行,第I+1行包含两个整数ki和si, ki表示第I门课的直接先修课,si表示第I门课的学分。若ki=0表示没有直接先修课(1<=ki<=N, 1<=si<=20)。
输出:
只有一行,选M门课程的最大得分。
样例:
输入:
7 4
2 2
0 1
0 4
2 1
7 1
7 6
2 2 输出:
13
解析:
这题比苹果树多了一个步骤就是把一棵普通树转化为二叉树。
读入数据时把二叉树建好:第一个孩子作为父节点的左子树,其它孩子作为第一个孩子的右子树。
F(x,y):表示节点x取y门课得最高学分,则
F(x,y)=max(f(xl,k-1)+xv+f(xr,y-k))k=0,1,y
f(xl,k-1)+xv(课程x的学分) :表示选了课程x,左孩子选k-1门课,共k门课。
f (xr,y-k)表示右孩子只能选y-k门课。
标程中节点-1表示空节点,0是根节点,1—n是n门可选课程的节点
思考:若本题加上选那些课程可得到这个最大学分,怎样修改程序?
实现:
怎么实现,是在竞赛中的很重要的一个问题,如果你想ac了这道题目的话,你应该熟悉怎么把一棵树转化成二叉树,完后怎么用递规的思想来实现动态规划。所以坚实的基础是很重要的东西,如果没有了基础,什么都是空中楼阁。
程序中已经边读边把二叉树建立好了。
源程序代码:
program bluewater;
type
tree=record
l,r,k:longint;
end;
var
s:string;
i,j,k,l:longint;
n,m:longint;
a:array[0200] of tree;
b:array[-1200,0150] of integer;
f:array[0200] of longint;
procedure treedp(x,y:longint);
var i,j,k,l:longint;
begin
if b[x,y]>=0 then exit;
treedp(a[x]r,y);{只有右子树的情况}
j:=b[a[x]r,y];
for k:=1 to y do{左右子树都有的情况}
begin
treedp(a[x]l,k-1);
treedp(a[x]r,y-k);
i:=b[a[x]l,k-1]+b[a[x]r,y-k]+a[x]k;
if i>j then j:=i;
end;
b[x,y]:=j;
end;
begin
readln(s);
assign(input,s);reset(input);
readln(n,m);
fillchar(f,sizeof(f),0);
for i:=0 to n do
begin a[i]l:=-1;a[i]r:=-1;a[i]k:=-1;end;
{build tree}
for i:=1 to n do
begin
readln(k,l);
a[i]k:=l;
if f[k]=0 then a[k]l:=i
else a[f[k]]r:=i;
f[k]:=i;
end;
{bianjie}
for i:=-1 to n do
for j:=-1 to m do
if (i=-1) or (j=0) then b[i,j]:=0 else b[i,j]:=-1;
{tree dp}
treedp(a[0]l,m);
{output}
writeln(b[a[0]l,m]);
end
Tju1053 技能树
Problem
玩过Diablo的人对技能树一定是很熟悉的。一颗技能树的每个结点都是一项技能,要学会这项技能则需要耗费一定的技能点数。
只有学会了某一项技能以后,才能继续学习它的后继技能。每项技能又有着不同的级别,级别越高效果越好,而技能的升级也是
需要耗费技能点数的。
有个玩家积攒了一定的技能点数,他想尽可能地利用这些技能点数来达到最好的效果。因此他给所有的级别都打上了分,他认为
效果越好的分数也越高。现在他要你帮忙寻找一个分配技能点数的方案,使得分数总和最高。
Input
该题有多组测试数据。
每组测试数据第一行是一个整数n(1<=n<=20),表示所有不同技能的总数。
接下来依次给出n个不同技能的详细情况。
每个技能描述包括5行。
第一行是该技能的名称。
第2行是该技能在技能树中父技能的名称,名称为None则表示该技能不需要任何的先修技能便能学习。
第3行是一个整数L(1<=L<=20),表示这项技能所能拥有的最高级别。
第4行共有L个整数,其中第I个整数表示从地I-1级升到第I级所需要的技能点数(0级表示没有学习过)。
第5行包括L个整数,其中第I个整数表示从第I-1级升级到第I级的效果评分,分数不超过20。
在技能描述之后,共有两行,第1行是一个整数P,表示目前所拥有的技能点数。
接下来1行是N个整数,依次表示角色当前习得的技能级别,0表示还未学习。这里不会出现非法情况。
Output
每组测试数据只需输出最佳分配方案所得的分数总和。
解析:这题是选课的加强版,但并难不倒我们
还是把一棵树转换为二叉树,完后从子节点到根节点作一次dp,最后得到最优解
由于和上题很相像就不写方程了。
源代码程序:
program bluewater;
type
tree=record
s,sf:string;
l,r,m:longint;
c:array[120] of longint;
d:array[120] of longint;
end;
var
i,j,k,l,m,n:longint;
a:array[020] of tree;
b:array[020] of longint;
learn:array[020] of longint;
f:array[020,08000] of longint;
function treedp(x,y:longint):longint;
var i,j,k,l,max,o,p,q:longint;
begin
if f[x,y]<>-1 then begin treedp:=f[x,y];exit;end;
max:=treedp(a[x]r,y);
{learn>0}
if learn[x]>0 then
begin
for k:=0 to y do
begin
i:=treedp(a[x]l,k)+treedp(a[x]r,y-k);
if i>max then max:=i;
end;
end;
{learn=0}
l:=0;p:=0;i:=0;
for o:=1 to a[x]m do
begin
if o>learn[x] then
begin l:=l+a[x]c[o];p:=p+a[x]d[o];end;
for k:=0 to y-l do
begin
i:=treedp(a[x]l,k)+treedp(a[x]r,y-l-k)+p;
if i>max then max:=i;
end;
end;
f[x,y]:=max;
treedp:=max;
end;
function find(x:string):longint;
var i,j:longint;
begin
for i:=0 to n do
if a[i]s=x then break;
find:=i;
end;
begin
while not(eof(input)) do
begin
{input}
readln(n);
fillchar(a,sizeof(a),0);
fillchar(b,sizeof(b),0);
a[0]s:='None';
for i:=1 to n do
with a[i] do
begin
readln(s);
readln(sf);
readln(m);
for j:=1 to m do read(c[j]);readln;
for j:=1 to m do read(d[j]);readln;
end;
readln(m);
if m>8000 then m:=8000;
for i:=1 to n do read(learn[i]);readln;
{build binary tree}
for i:=1 to n do
begin
k:=find(a[i]sf);
if b[k]=0 then
begin b[k]:=i;a[k]l:=i;end
else begin a[b[k]]r:=i;b[k]:=i;end;
end;
{bian jie}
for i:=0 to 20 do
for j:=0 to 8000 do
f[i,j]:=-1;
for i:=0 to 8000 do f[0,i]:=0;
{main}
writeln(treedp(a[0]l,m));
end;
end
战略游戏
Problem
Bob喜欢玩电脑游戏,特别是战略游戏。但是他经常无法找到快速玩过游戏的办法。现在他有个问题。
他要建立一个古城堡,城堡中的路形成一棵树。他要在这棵树的结点上放置最少数目的士兵,使得这些士兵能了望到所有的路。
注意,某个士兵在一个结点上时,与该结点相连的所有边将都可以被了望到。
请你编一程序,给定一树,帮Bob计算出他需要放置最少的士兵
Input
第一行为一整数M,表示有M组测试数据
每组测试数据表示一棵树,描述如下:
第一行 N,表示树中结点的数目。
第二行至第N+1行,每行描述每个结点信息,依次为:该结点标号i,k(后面有k条边与结点I相连)。
接下来k个数,分别是每条边的另一个结点标号r1,r2,,rk。
对于一个n(0<n<=1500)个结点的树,结点标号在0到n-1之间,在输入数据中每条边只出现一次。
Output
输出文件仅包含一个数,为所求的最少的士兵数目。
例如,对于如下图所示的树:
答案为1(只要一个士兵在结点1上)。
Sample Input
2
4
0 1 1
1 2 2 3
2 0
3 0
5
3 3 1 4 2
1 1 0
2 0
0 0
4 0
Sample Output
1
2
Source
sgoi
分析:这题有2种做法,一种是比较简单但不是很严密的贪心,如果测试数据比较刁钻的话就不可能ac,而这题是一道比较典型的树型动态规划的题目,这题不但要考虑子节点对他的根节点的影响,而且每放一个士兵,士兵所在位置既影响他的子节点也影响了他的根节点。不过状态还是很容易来表示的,动规实现也不是很难,不过这在这些例题中也有了些“创新”了。而且这题不是一个对二叉树的dp,而是对一颗普通树的dp,所以更具代表性。
源程序代码:
program bluewater;
const
maxn=1500;
var
i,j,k,l:longint;
m,n,p,q:longint;
a:array[0maxn,0maxn] of boolean;
b:array[0maxn] of longint;
c:array[0maxn] of boolean;
function leaf(x:longint):boolean;
var i,j:longint;
t:boolean;
begin
t:=true;
for i:=0 to n-1 do
if a[x,i] then begin t:=false;break;end;
leaf:=t;
end;
function treedp(x:longint):longint;
var i,j,k,l:longint;
begin
j:=0;{add}
k:=0;{leaf}
l:=0;{not put not leaf}
for i:=0 to n-1 do
if (a[x,i]) and (x<>i) then
if leaf(i) then inc(k) else
begin
j:=j+treedp(i);
if not(c[i]) then inc(l);
end;
{puanduan}
if (k>0) or (l>0) then begin c[x]:=true;treedp:=j+1;exit;end;
if (j>0) and (l=0) then begin treedp:=j;exit;end;
end;
begin
{input}
readln(m);
for p:=1 to m do
begin
fillchar(b,sizeof(b),0);
fillchar(a,sizeof(a),false);
fillchar(c,sizeof(c),false);
readln(n);
for i:=1 to n do
begin
read(k,l);
for j:=1 to l do
begin
read(q);
a[k,q]:=true;
b[q]:=1;
end;
readln;
end;
{main}
for i:=0 to n-1 do
if b[i]=0 then break;
fillchar(b,sizeof(b),0);
if leaf(i) then writeln('1') else writeln(treedp(i));
end;
end
Ural 1039 没有上司的晚会
背景
有个公司要举行一场晚会。
为了能玩得开心,公司领导决定:如果邀请了某个人,那么一定不会邀请他的上司
(上司的上司,上司的上司的上司……都可以邀请)。
题目
每个参加晚会的人都能为晚会增添一些气氛,求一个邀请方案,使气氛值的和最大。
输入格式
第1行一个整数N(1<=N<=6000)表示公司的人数。
接下来N行每行一个整数。第i行的数表示第i个人的气氛值x(-128<=x<=127)。
接下来每行两个整数L,K。表示第K个人是第L个人的上司。
输入以0 0结束。
输出格式
一个数,最大的气氛值和。
样例输入
7
1
1
1
1
1
1
1
1 3
2 3
6 4
7 4
4 5
3 5
0 0
样例输出
5
>
model small
stack 8192
data
mode dw
jmptbl dw l0,l1,l2,l3,l4,l5,l6,l7
prompt db 'press a numeric key [07]',13,10,36
errmsg db 'Invalid keypress!$'
code
main: mov ax,@data
mov ds,ax
mov dx,offset prompt
mov ah,9
int 21h
mov ah,1
int 21h
sub al,'0'
mov ah,0
mov mode,ax
mov bx,mode
cmp bx,7
ja illegal
add bx,bx
jmp jmptbl [bx]
illegal:
mov dx,offset errmsg
mov ah,9
int 21h
quit: mov ah,4ch
int 21h
l0: mov dl,'0'
jmp quit
l1: mov dl,'1'
jmp quit
l2: mov dl,'2'
jmp quit
l3: mov dl,'3'
jmp quit
l4: mov dl,'4'
jmp quit
l5: mov dl,'5'
jmp quit
l6: mov dl,'6'
jmp quit
l7: mov dl,'7'
jmp quit
end main
这个构想实际上来源于一个全选的组件;即一开始的目的是做一个全选组件,然后在完成的时候被告知可能有多层级列表的情况;由于项目所用的vux组件库没有tree这个组件;于是干脆想着改造一下尝试实现一个tree结构。
21、局限和前提
211,发现无法在子节点里直接修改节点的props传过来的值了
解决方案:
在每一层子节点的data属性里定义一个变量,用于存储深拷贝(props传过来的值)后的值
深拷贝方法用Objectassign
212,由于无法直接在子节点里直接修改props传过来的值,那么会出现以下情况
1)子节点里的状态发生变更时,得一层一层冒泡到根节点才能去修改当前Tree渲染的数据源里对应的分支节点的数据,因为,对于每一层子节点而言,它的数据源来源于上一节点通过props传过来的数据
2)深拷贝虽然解决了在子节点的作用域下的一些状态无法发生变更(这句话的意思是,比如当前节点有一个属性控制下一分支列表的显隐,那么当该分支列表的结构层的渲染数据直接取得props传过来的data,由于该data不能修改,那么该属性控制显隐的功能就失效了)
但是同时也带来了父节点与子节点的解耦,当父节点的数据源发生变更时,如果不去watch的话,是没办法及时通知子节点发生对应属性的变更的;而vue的生命周期在组件层次只有mounted可以用,而该生命周期在一次会话里只会执行一次,即父节点的变动不会引发子节点的mounted周期;(若是想,似乎可以考虑在父节点引用的子节点出绑定一个key)
即<div class='parent'>
<child-component :key = 'dataid' :data = 'data' />
</div>
22、树组件的具体实现
221、前提
1)下行逻辑:
对于每一个分支节点而言,它既是上一个节点的子节点,同样也是下一分支树的根节点;对于每一个分支节点而言,如果它被选中了,则其下如果有分支(树),则都会被选中,这是全选的概念
2)上行逻辑:
由于每一个分支节点同时是上一节点的子节点,那么意味着,当它被选中时,上一分支节点需要做全选判断(如果该分支下所有子节点都处于选中状态,则该分支节点处于全选状态)
222、思路:
1)选中和取消选中用两个数组来实现(下边将选中的存储数组定义为a, 取消的为b):
每一个分支节点在执行选中 *** 作时,往a数组里推进该分支节点,同时判断该分支节点是否存在于b数组里,若存在,则将其从b数组中取出
每一个分支节点在执行取消选中时,往b数组里推进该分支节点,同时判断a数组里是否存在该节点,若存在,则取出
2)自上而下的 *** 作:
每一个分支节点在执行选中(取消)时,在将该节点的选中状态改变后,若该节点下存在分支(树),则循环遍历调用每一个子节点的选中 *** 作方法,并将(父节点的)变更后的选中状态传递下去,如图:
由于Tree在实现的过程中,本身就是递归调用分支树组件的形式来实现,所以上述的逻辑会层层调用,最终实现自上而下的状态变更
3)自下而上的 *** 作:
由于前提2,每一个分支节点在选中的状态发生变更后,需要将状态更新至其上一层节点,并在上一层节点里触发全选的判断,该判断需要区分取消和选中两种状态,不然会引发整个树的状态紊乱:
基于思路1:
在父节点里,若触发全选判断的子节点的状态为取消选中, 则该父节点无论之前什么状态,此时应该为取消选中状态,具体实现:
上述思路为:若当前父节点下的所有子节点里,只要有一个子节点不存在于选中列表(该列表用于存放所有处于选中状态的节点),则取消该父节点的选中状态;同时需要将其从选中列表中剔除;并且需要冒泡到上层节点
若触发全选判断的子节点的状态为选中状态,则需要判断当前取消选中的列表集里是否存在当前父节点下的直属子节点,只要有一个符合条件,意味着当前父节点下存在未选中的节点;否则该父节点处于全选状态,具体实现:
上述思路为:当该节点下的所有子节点处于选中状态(即不存在于未选中列表集里)时,将该节点的选中状态置为true;同时往选中列表集里推入该父节点;同时向上层冒泡触发上层节点的全选判断
4)选中/取消选中的相关实现:
选中/取消选中需要实现以下逻辑:
a)变更当前的选中状态
b)(递归)调用下一节点的选中/取消的方法
c)根据当前节点的选中状态来决定是推入a数组还是b数组(a、b数组为322的思路1)里提到的两个集合)
d)若当前节点的选中/取消方法是点击触发的,则触发上层冒泡事件(需要判断是点击与否是因为如果不判断,由于逻辑b会递归调用子节点的方法,则最终会形成一次自下而上(至当前节点终止)的冒泡事件调用,而实际上自上而下的过程中就已经决定了在该分支树上的节点判断,所以此时发生在该分支树上的冒泡是多余的
具体实现:
实现过程中有个意外的bug:这个bug是这么产生的,由于我在选中的冒泡逻辑里做了如下出来:
这个逻辑有个致命之处在于最开始的时候如果从下层节点开始选择,则未选中节点列表unKeys一开始是空的,这意味着会出现如下情况:
1)一个父节点有a、b、c三个节点
2)当a节点被选中的时候,尽管b和c节点没有被选中,但由于unKeys为空,那么b,c节点顺利绕过了判断
3)于是checkAll的值成了true
4)于是开始进行错误的冒泡
然后,优化后的实现:
以上就是关于求数据结构 B-树与B+树及其 *** 作的代码(C语言版)全部的内容,包括:求数据结构 B-树与B+树及其 *** 作的代码(C语言版)、请问一下这种树状思维导图是用什么软件做的或者有什么好用的思维导图制作软件推荐、树形动态规划建树的思路与pascal的代码求助啊求助~~~~谢谢啊谢谢~~~~等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)