数据结构C语言版 树的双亲表存储表示Word文档格式.docx

上传人:b****5 文档编号:21509923 上传时间:2023-01-30 格式:DOCX 页数:16 大小:19.29KB
下载 相关 举报
数据结构C语言版 树的双亲表存储表示Word文档格式.docx_第1页
第1页 / 共16页
数据结构C语言版 树的双亲表存储表示Word文档格式.docx_第2页
第2页 / 共16页
数据结构C语言版 树的双亲表存储表示Word文档格式.docx_第3页
第3页 / 共16页
数据结构C语言版 树的双亲表存储表示Word文档格式.docx_第4页
第4页 / 共16页
数据结构C语言版 树的双亲表存储表示Word文档格式.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

数据结构C语言版 树的双亲表存储表示Word文档格式.docx

《数据结构C语言版 树的双亲表存储表示Word文档格式.docx》由会员分享,可在线阅读,更多相关《数据结构C语言版 树的双亲表存储表示Word文档格式.docx(16页珍藏版)》请在冰豆网上搜索。

数据结构C语言版 树的双亲表存储表示Word文档格式.docx

'

;

//以空格符为空

intInitTree(PTree*T)

{//操作结果:

构造空树T

(*T).n=0;

return1;

}

voidDestroyTree()

{

//由于PTree是定长类型,无法销毁

//构造一个空队列Q

intInitQueue(LinkQueue*Q)

(*Q).front=(*Q).rear=(QueuePtr)malloc(sizeof(QNode));

//动态分配一个空间

if(!

(*Q).front)

exit(0);

(*Q).front->

next=NULL;

//队头指针指向空,无数据域,这样构成了一个空队列

//若Q为空队列,则返回1,否则返回0

intQueueEmpty(LinkQueueQ)

if(Q.front==Q.rear)

return1;

else

return0;

//插入元素e为Q的新的队尾元素

intEnQueue(LinkQueue*Q,QElemTypee)

QueuePtrp=(QueuePtr)malloc(sizeof(QNode));

p)//存储分配失败

//生成一个以为e为数据域的队列元素

p->

data=e;

//将该新队列元素接在队尾的后面

(*Q).rear->

next=p;

(*Q).rear=p;

//若队列不空,删除Q的队头元素,用e返回其值,并返回1,否则返回0

intDeQueue(LinkQueue*Q,QElemType*e)

QueuePtrp;

if((*Q).front==(*Q).rear)

p=(*Q).front->

next;

//队头元素

*e=p->

data;

next=p->

if((*Q).rear==p)

(*Q).rear=(*Q).front;

free(p);

//构造树T

intCreateTree(PTree*T)

LinkQueueq;

QElemTypep,qq;

inti=1,j,l;

charc[MAX_TREE_SIZE];

//临时存放孩子结点数组

InitQueue(&

q);

//初始化队列

printf("

请输入根结点(字符型,空格为空):

"

);

scanf("

%c%*c"

&

(*T).nodes[0].data);

//根结点序号为0,%*c吃掉回车符

if((*T).nodes[0].data!

=Nil)//非空树

{

(*T).nodes[0].parent=-1;

//根结点无双亲

qq.name=(*T).nodes[0].data;

qq.num=0;

EnQueue(&

q,qq);

//入队此结点

while(i<

MAX_TREE_SIZE&

&

!

QueueEmpty(q))//数组未满且队不空

{

DeQueue(&

q,&

qq);

//出队一个结点

printf("

请按长幼顺序输入结点%c的所有孩子:

qq.name);

gets(c);

l=strlen(c);

for(j=0;

j<

l;

j++)

{

(*T).nodes[i].data=c[j];

(*T).nodes[i].parent=qq.num;

p.name=c[j];

p.num=i;

EnQueue(&

q,p);

i++;

}

}

if(i>

MAX_TREE_SIZE)

结点数超过数组容量\n"

exit(0);

(*T).n=i;

}

(*T).n=0;

#defineClearTreeInitTree//二者操作相同

//若T为空树,则返回1,否则返回0

intTreeEmpty(PTreeT)

if(T.n)

//返回T的深度

intTreeDepth(PTreeT)

intk,m,def,

max=0;

//存储深度

for(k=0;

k<

T.n;

++k)

def=1;

//初始化本际点的深度

m=T.nodes[k].parent;

while(m!

=-1)

m=T.nodes[m].parent;

def++;

if(max<

def)

max=def;

returnmax;

//最大深度

//返回T的根

TElemTypeRoot(PTreeT)

inti;

for(i=0;

i<

i++)

if(T.nodes[i].parent<

0)

returnT.nodes[i].data;

returnNil;

//返回第i个结点的值

TElemTypeValue(PTreeT,inti)

if(i<

T.n)

returnT.nodes[i].data;

returnNil;

//改cur_e为value

intAssign(PTree*T,TElemTypecur_e,TElemTypevalue)

intj;

for(j=0;

(*T).n;

if((*T).nodes[j].data==cur_e)

(*T).nodes[j].data=value;

return1;

return0;

//若cur_e是T的非根结点,则返回它的双亲,否则函数值为"空"

TElemTypeParent(PTreeT,TElemTypecur_e)

for(j=1;

j<

T.n;

j++)//根结点序号为0

if(T.nodes[j].data==cur_e)

returnT.nodes[T.nodes[j].parent].data;

//若cur_e是T的非叶子结点,则返回它的最左孩子,否则返回"空"

TElemTypeLeftChild(PTreeT,TElemTypecur_e)

inti,j;

if(T.nodes[i].data==cur_e)//找到cur_e,其序号为i

break;

for(j=i+1;

j++)//根据树的构造函数,孩子的序号>其双亲的序号

//根据树的构造函数,最左孩子(长子)的序号<其它孩子的序号

if(T.nodes[j].parent==i)

returnT.nodes[j].data;

//若cur_e有右(下一个)兄弟,则返回它的右兄弟,否则返回"空"

TElemTypeRightSibling(PTreeT,TElemTypecur_e)

if(T.nodes[i].data==cur_e)//找到cur_e,其序号为i

if(T.nodes[i+1].parent==T.nodes[i].parent)

//根据树的构造函数,若cur_e有右兄弟的话则右兄弟紧接其后

returnT.nodes[i+1].data;

//输出树T

intPrint(PTreeT)

结点个数=%d\n"

T.n);

结点双亲\n"

printf("

%c"

Value(T,i));

//结点

if(T.nodes[i].parent>

=0)//有双亲

Value(T,T.nodes[i].parent));

//双亲

\n"

//插入c为T中p结点的第i棵子树

intInsertChild(PTree*T,TElemTypep,inti,PTreec)

intj,k,l,f=1,n=0;

//设交换标志f的初值为1,p的孩子数n的初值为0

PTNodet;

TreeEmpty(*T))//T不空

for(j=0;

j++)//在T中找p的序号

if((*T).nodes[j].data==p)//p的序号为j

break;

l=j+1;

//如果c是p的第1棵子树,则插在j+1处

if(i>

1)//c不是p的第1棵子树

for(k=j+1;

k<

(*T).n;

k++)//从j+1开始找p的前i-1个孩子

if((*T).nodes[k].parent==j)//当前结点是p的孩子

{

n++;

//孩子数加1

if(n==i-1)//找到p的第i-1个孩子,其序号为k1

break;

}

l=k+1;

//c插在k+1处

}//p的序号为j,c插在l处

if(l<

(*T).n)//插入点l不在最后

//依次将序号l以后的结点向后移c.n个位置

for(k=(*T).n-1;

k>

=l;

k--)

(*T).nodes[k+c.n]=(*T).nodes[k];

//向后移c.n个位置

if((*T).nodes[k].parent>

=l)

(*T).nodes[k+c.n].parent+=c.n;

for(k=0;

c.n;

k++)

(*T).nodes[l+k].data=c.nodes[k].data;

//依次将树c的所有结点插于此处

(*T).nodes[l+k].parent=c.nodes[k].parent+l;

(*T).nodes[l].parent=j;

//树c的根结点的双亲为p

(*T).n+=c.n;

//树T的结点数加c.n个

while(f)

{//从插入点之后,将结点仍按层序排列

f=0;

//交换标志置0

for(j=l;

(*T).n-1;

j++)

if((*T).nodes[j].parent>

(*T).nodes[j+1].parent)

//如果结点j的双亲排在结点j+1的双亲之后(树没有按层序排

//列),交换两结点

t=(*T).nodes[j];

(*T).nodes[j]=(*T).nodes[j+1];

(*T).nodes[j+1]=t;

f=1;

//交换标志置1

for(k=j;

k++)//改变双亲序号

if((*T).nodes[k].parent==j)

(*T).nodes[k].parent++;

//双亲序号改为j+1

elseif((*T).nodes[k].parent==j+1)

(*T).nodes[k].parent--;

//双亲序号改为j

else//树T不存在

intdeleted[MAX_TREE_SIZE+1];

//删除标志数组(全局量)

//删除T中结点p的第i棵子树

voidDeleteChild(PTree*T,TElemTypep,inti)

intj,k,n=0;

QElemTypepq,qq;

=(*T).n;

deleted[j]=0;

//置初值为0(不删除标记)

pq.name='

a'

//此成员不用

if((*T).nodes[j].data==p)

//j为结点p的序号

for(k=j+1;

if((*T).nodes[k].parent==j)

n++;

if(n==i)

//k为p的第i棵子树结点的序号

if(k<

(*T).n)//p的第i棵子树结点存在

n=0;

pq.num=k;

deleted[k]=1;

//置删除标记

n++;

q,pq);

while(!

QueueEmpty(q))

for(j=qq.num+1;

if((*T).nodes[j].parent==qq.num)

pq.num=j;

deleted[j]=1;

EnQueue(&

if(deleted[j]==1)

for(k=j+1;

deleted[k-1]=deleted[k];

(*T).nodes[k-1]=(*T).nodes[k];

if((*T).nodes[k].parent>

j)

(*T).nodes[k-1].parent--;

j--;

(*T).n-=n;

//n为待删除结点数

//层序遍历树T,对每个结点调用函数Visit一次且仅一次

voidTraverseTree(PTreeT,void(*Visit)(TElemType))

Visit(T.nodes[i].data);

 

voidvi(TElemTypec)

%c"

c);

intmain()

PTreeT,p;

TElemTypee,e1;

InitTree(&

T);

构造空树后,树空否?

%d(1:

是0:

否)树根为%c树的深度为%d\n"

TreeEmpty(T),Root(T),TreeDepth(T));

CreateTree(&

构造树T后,树空否?

层序遍历树T:

TraverseTree(T,vi);

请输入待修改的结点的值新值:

%c%*c%c%*c"

e,&

e1);

Assign(&

T,e,e1);

层序遍历修改后的树T:

%c的双亲是%c,长子是%c,下一个兄弟是%c\n"

e1,

Parent(T,e1),LeftChild(T,e1),RightSibling(T,e1));

建立树p:

p);

层序遍历树p:

TraverseTree(p,vi);

将树p插到树T中,请输入T中p的双亲结点子树序号:

%c%d%*c"

i);

InsertChild(&

T,e,i,p);

Print(T);

删除树T中结点e的第i棵子树,请输入ei:

%c%d"

DeleteChild(&

T,e,i);

system("

pause"

输出效果:

1(1:

否)树根为树的深度为0

a

请按长幼顺序输入结点a的所有孩子:

bc

请按长幼顺序输入结点b的所有孩子:

d

请按长幼顺序输入结点c的所有孩子:

e

请按长幼顺序输入结点d的所有孩子:

请按长幼顺序输入结点e的所有孩子:

0(1:

否)树根为a树的深度为3

abcde

ef

abcdf

f的双亲是c,长子是,下一个兄弟是

A

请按长幼顺序输入结点A的所有孩子:

B

请按长幼顺序输入结点B的所有孩子:

AB

b2

结点个数=7

结点双亲

ba

ca

db

Ab

fc

BA

a1

结点个数=3

请按任意键继续...

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 中国风

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1