树形结构Word格式文档下载.docx
《树形结构Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《树形结构Word格式文档下载.docx(17页珍藏版)》请在冰豆网上搜索。
(2)对于任意一棵二叉树,如果其叶结点数为N0,而度数为2的结点(有左右子节点)总数为N2,则N0=N2+1;
如上图(左):
N0=6,N2=5右图:
N0=8,N2=7(3)有N个结点的完全二叉树各结点如果用顺序方式表示,则结点之间有如下关系:
·
如果I<
>
1,则其父结点的编号为[I/2];
如果2*I<
=N,则其左儿子(即左子树的根结点)的编号为2*I;
若2*I>
N,则无左儿子;
·
如果2*I+1<
=N,则其右儿子的结点编号为2*I+1;
若2*I+1>
N,则无右儿子。
(4)具有n个节点的完全二叉树的深度为[log2N]+1
4.二叉树的存储结构:
(1)顺序存储方式
图5
问题:
对于用顺序结构来表示的二叉树
A.如何根据节点顺序编号确定所层数和从左数起的编号;
反之如何根据层数和从左数起的编号确定节点顺序编号
B.如何根据节点顺序编号确定其父节点编号。
C.如何根据节点顺序编号确定其左右子节点编号
(2)链表存储方式,
A.采用数组类型
constmax=……{二叉树的存储容量}
TYPE
Datetype=……{节点信息类型}
Nodetype=recod
Data:
datatype;
{信息域}
Lchild,rchild:
integer;
{左右指针}
End;
VARlist:
array[1..max]ofnodetype;
应用形式:
list[I].data=……
list[list[I].lchild]:
=....{左节点}
list[list[I].rchild]:
=....{右节点}
如:
数组下标:
1 2 3 4 5 6 7 8
数组D:
A B C D E F G H
左指针数组L:
2 4 6 0 7 0 0 0
右指针数组R:
3 5 0 0 0 8 0 0
B.采用动态数据类型
type
datatype=....
link=^nodetype
nodetype=recod
data:
lchild,rchild:
link;
end;
VARt:
t^.data:
=....;
t^.lchild:
=..;
{左子节点}t^.rchild:
{右子节点}
5.二叉树的遍历运算(递归定义)
A
BC
DEF
GHI
图6
(1)先序遍历ABDEGCFHI
递归定义
访问根;
按先序遍历左子树;
按先序遍历右子树。
算法如下
动态类型数组类型
typeconstmax=……
datatype=....Datetype=……
link=^nodetypeNodetype=recod
nodetype=recodData:
L,r:
l,r:
proceduremake(t:
link);
proceduremake(t:
intger);
beginbegin
ift<
nilthenift<
0then
访问t^.data访问list[t].data
make(t^.l);
make(list[t].l);
make(t^.r);
make(list[t].r);
(2)中序遍历DBGEACHFI
按中序遍历左子树;
按中序遍历右子树
make(list[t].l)
(3)后序遍历DGEBHIFCA
按后序遍历左子树;
按后序遍历右子树;
访问根
练习题
1.用顺序存储方式建立一棵深度为N(N<
6)的满二叉树,并对其进行先序遍历。
(tree1.pas)
2.用链表存储方式建立一棵如图5所示的二叉树,并对其进行先序遍历。
(tree2.pas)
3.如图所示的二叉树,按先序边历读入字符串ABC##DE#G##F###(其中#表示对应的指针为空格),试用链表存储方式建立二叉数,然后用中序边历输出。
(tree4.pas)
参考程序
【tree1.pas】
programtree1;
var
b:
array[1..31]ofchar;
e:
array[1..63]ofbyte;
n,h,i,k:
proceduretree(t:
integer);
begin
ife[t]=0thenexit
elsebegin
write(b[t]);
e[t]:
=0;
t:
=2*t;
tree(t);
=t+1;
end;
repeat
write('
n='
);
readln(n);
until(n>
0)and(n<
6);
fillchar(e,sizeof(e),0);
k:
=trunc(exp(n*ln
(2)))-1;
fori:
=1tokdo
e[i]:
=1;
=1to26do
b[i]:
=chr(64+i);
=1to5do
b[26+i]:
=chr(48+i);
h:
tree(h);
writeln;
end.
【tree2.pas】
programtree2;
const{人工建立二叉树的链表关系}
a:
array[1..8]ofchar=('
A'
'
B'
C'
D'
E'
F'
G'
H'
r:
array[1..8]ofinteger=(3,5,0,0,0,8,0,0);
l:
array[1..8]ofinteger=(2,4,6,0,7,0,0,0);
array[1..7]ofinteger;
proceduresearch(m:
ife[m]=0thenbegin
write(a[m]);
e[m]:
=1
if(l[m]=0)and(r[m]=0)thenexit
ifl[m]<
0thensearch(l[m]);
ifr[m]<
0thensearch(r[m]);
search
(1);
【tree4.pas】仅给出建树过程
procedurecrt(varbt:
指针记录类型){按先序边历建树过程}
VAR....
Begin
Read(ch);
Ifch=’#’thenbt:
=nil
Else
New(bt);
bt^.data:
=ch;
{建根节点}
Crt(bt^.l);
{建左子树}
Crt(bt^.r);
{建右子树}
6.二叉排序树
排序树T是一棵按中序已分类的二叉树,即对于树的每个节点(包括顶点),值比它小的那些节点都在它的左边,值比它大的的右边。
按中序遍历,即可得到各个节点的信息域(data)按从小到大顺序的序列。
如图是一棵二叉排序树:
7
3
11
15913
(1)下列过程是以tree为根的一棵排序二叉中插入一个信息域值为newdata的节点。
Procedureinsert(vartree:
link;
newdata:
datatype);
Begin
Iftree=nilthen
New(tree);
Tree^.l:
=nil;
tree^.r:
tree^.data:
=newdata;
{插入新节点}
End
Else
Ifnewdata<
tree^.datathen
Insert(tree^.l,newdata);
{新节点插在左子树中,以tree^.l为子树继续寻找插入位置}
Else
Insert(tree^.r,newdata);
{新节点插在右子树中,以tree^.r为子树继续寻找插入位置}
主程序框架如下
vartemp:
datatype;
{节点类型}
root:
link;
{根}
begin
repeet
read(temp);
iftemp<
’#’then{#是结束标志}
insert(root,temp);
untiltemp=’#’
end.
(2)如何在一棵二叉排序树中找出具有关键字V的节点,我们可采用分割查找,程序如下:
procedurefind(t:
v:
datatype);
ift=nilthen
writeln(‘Notfind!
’);
exit;
else
ift^.data>
vthenfind(t^.l);
elseift^.data<
vthenfind(t^.r);
writeln(‘find!
(3)练习题
.给出一组数据:
R={10.18,3,8,12,2,7,3},试编程序,先构造一棵二叉排序树,然后以中序遍历访问所得到的二叉树(即按数据域的值从小到大输出),并输出遍历结果。
(tree3.pas)
【tree3.pas】构造的二叉排序树如下
programtree3;
const
array[1..8]ofinteger=(10,18,3,8,12,2,7,3);
point=^nod;
nod=record
w:
right,left:
point;
first:
j,k:
procedurehyt(d:
varp:
point);
ifp=nilthenbegin
new(p);
ifk=1thenbegin
=p;
=2
withp^do
=d;
right:
left:
end
ifd>
=wthenhyt(d,right)elsehyt(d,left);
procedurehyt1(p:
ifleft<
nilthenhyt1(left);
write(w:
4);
ifright<
nilthenhyt1(right);
forj:
=1to8dohyt(a[j],first);
hyt1(first);
writeln
6.普通树转换成二叉树:
凡是兄弟就用线连起来,然后去掉父亲到儿子的连线,只留下父母到其第一个子女的连线。
AA
BCDB
EFGHIEC
普通树FD
GH
转换成二叉树I
四、例:
1.给出八枚金币a,b,c,d,e,f,g,h,编程以称最少的次数,判定它们蹭是否有假币,如果有,请找出这枚假币,并判定这枚假币是重了还是轻了。