北工大数据结构上机实验报告3教材.docx

上传人:b****8 文档编号:11174554 上传时间:2023-02-25 格式:DOCX 页数:18 大小:28.14KB
下载 相关 举报
北工大数据结构上机实验报告3教材.docx_第1页
第1页 / 共18页
北工大数据结构上机实验报告3教材.docx_第2页
第2页 / 共18页
北工大数据结构上机实验报告3教材.docx_第3页
第3页 / 共18页
北工大数据结构上机实验报告3教材.docx_第4页
第4页 / 共18页
北工大数据结构上机实验报告3教材.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

北工大数据结构上机实验报告3教材.docx

《北工大数据结构上机实验报告3教材.docx》由会员分享,可在线阅读,更多相关《北工大数据结构上机实验报告3教材.docx(18页珍藏版)》请在冰豆网上搜索。

北工大数据结构上机实验报告3教材.docx

北工大数据结构上机实验报告3教材

上机题三报告

姓名:

学号:

完成日期:

2015年5月5日

题目:

表达式可以用表达式二义树来表示。

对于简单的四则运算表达式,请实现以下功能;

(1)对于任意给出的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号),能够在计算机内部构造出一棵表达式二义树,并且以图示显示出来(字符图或图形的形式)。

(2)对于构造好的内部表达式二叉树,按照用户要求,输出相应的前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号).

一、需求分析

1.输入形式、输入值的范围;输入前缀表达式(不带括号)、中缀表达式(可以带括号)或后缀表达式(不带括号)

2.输出形式^表达式二叉树,前缀表达式、中缀表达式和后缀表达式。

3・程序功能;用表达式二叉树表示表达式,并转换为前缀表达式、中缀表达式或后缀表达式。

4.测试数据

正确的输入输出:

为为为达达达表表表241

错误的输入输出:

请输入字符串表达式:

23+11/304

1/

34

中缀表达式为=1+3/4雪建i轲为=必4后缀衾达式为=134/+

二、概要设计

1.ADT定义

classTNode//W点类

2.主程序流程

 

 

3.各程序模块间的调用关系

Main()

求二叉树表达式模块

求前、中、后缀表达式模块

打印树

删除树

 

三、详细设计

1.实现ADT定义的数据类型

classTNode//节点类

{public:

charoper;//数据域,为简便起见,操作数用单个字符代替

TNode*left;

TNode*right;

ints;intt;〃计算树的层数使用

TNode()//缺省构造函数

{left二right二NULL;

opei-O;

}

TNode(charop)//赋值构造函数

{left二right二NULL;

opei-op;

}

1;

2.算法描述

表达式转化为二叉树

voidpre2tree(TNode*&p,stringstr)//#缀表达式生成二叉树

{碰到操作数则把英值赋给相应的新申请的二叉树结点,地址压栈:

碰到操作符则把其值赋给相应的新申请的二叉树,并从栈中弹出两个地址,

分别作为英左指针和右指针,然后再把其地址压栈,最后一个地址即为二叉树的根结点地址。

voidpost2tree(TNode*&p^stringstr)//后缀表达式生成二叉树

{〃碰到操作数则把英值赋给相应的新申请的二叉树结点,若栈为空则地址压栈,

〃碰到操作符则把其值赋给相应的新申请的二叉树结点,取栈顶元素,

〃若当前元素的左孩子为空则设为其左孩子,

〃左孩子为满则设为其右孩子,开始那个元素地址为根结点地址,开始时用变量root保存。

}

voidin2tree(TNode*&p,stringstr)//中缀表达式转换成后缀表达式生成二叉树

{从中缀表达式中自左至右依次读入各个字符。

如果读入操作数,直接输出到后缀表达式。

如果读入的是运算符,并且运算符栈为空,则将该运算符宜接进栈:

如果栈不

为空,则比较该运算符和栈顶运算符的优先级。

若该运算符高于栈顶运算符的优先级,则将该运算符直接进栈:

若该运算符低于或等于栈顶运算符的优先级,则将栈中高于或等于该运算符优先

级的元素依次出栈输出到后缀表达式中,然后再将该运算符进栈。

在碰到开括号和栈为空前反复弹出栈中元素

若栈非空栈顶不是左括号且栈顶元素优先级不低于输入运算符时,

/将栈顶元素弹岀到后缀表达式

}

二叉树表达式转化为表达式

voidpostOrdcr(TNode*p)〃先序遍历

{if(P)

{postOrder(p->left);

postOrder(p->right);

cout«p->oper;

}

voidpreOrder(TNode*p)//后序遍历

{if(P)

{cout«p->oper;

preOrder(p->left);

preOrder(p->right);

voidinOrder(TNodc幺p)〃中序遍历,同时输出不带冗余括号的中缀表达式

{if(P)

if(p->left)

{if(如果当前节点的左子树是运算符,且运算符优先级低于当前运算符,

那么左边的表达式要先il•算,需要加括号)

{

cout«H(H;

inOrder(p->left);

cout«H)M;

}

else//否则直接输出左子树

inOrdcr(p->left);

}

cout«p->opcr;〃输出当前巧点

if(p->right)

{if(如果当前节点的右子树是运算符,且运算符优先级不高于当前运算符,

那么右边的表达式要先计算,需要加括号)

{

cout«H(n;

inOrder(p->right);

cout«,r)M;

}

else

inOrder(p->right);

四、程序测试

n

Pl

鬧输入字符串表达式,

-*4-2325

3■■:

r

駡输入字符串表达式:

K2+3)*2-5

吃5-

M2石

>3兴

+3+2吃

2*3

<-2第知站迄达2表表表

*3缀缀缀+2虫聲

 

養输入字符串表达式:

23+2*5-

为为为达达达表表表3缀缀缀2中曹

五、用户使用说明

运行程序后,按照提示选择表达式类型(-1:

前缀表达式;0:

中缀表达式:

1:

后缀表达式)然后输入相应的表达式,回车后可以得到二叉树表达式及出前缀、中缀、后缀表达式

六、源程序

#include

#includc

#includc

#include

#include

usingnamespacestd;

classTNode//节点类

{public:

charoper7/数据域,为简便起见,操作数用单个字符代替

TNode*left;

TNode*right;

ints;intW树的层数使用

TNode()//缺省构造函数

{Ieft=right=NULL;

oper=0;

}

TNode(charop)//赋值构造函数

{left=right=NULL;

oper=op;

}

};

boolisOper(charop)〃判断是否为运算符

{

charoper[]={,(,;)\,+,,'-',

for(inti=0;i

i++)

{if(op=oper[i])

{

returntme;

}

returnfalse;

}

intgetOperOrder(charop)//返回运算符op所对应的优先级

{//左括号优先级,加减号为,乘除号为,方幕为,右括号,栈底返回switch(op){caser:

return1;

case屮:

case"clum2;

case

case7:

return3;case,A,:

return4;default:

〃龙义在栈中的右括号和栈底字符的优先级最低

return0;

}

voidfreeTree(TNode*&p)//递归删除树

{

if(p->left!

=NULL)

freeTree(p->left);

if(p->right!

=NULL)freeTree(p->right);

delete(p);

}

voidpostOrder(TNode*p)〃先序遍历

{if(P)

{postOrder(p->left);

postOrder(p->right);

cout«p->oper;

}

}

voidpreOrder(TNodc*p)//后序遍历

{if(P)

{cout«p->oper;

preOrder(p->left);

preOrder(p->right);

}}

voidinOrder(TNode幺p)〃中序遍历,同时输出不带冗余括号的中缀表达式

{if(P)

{

if(p->left)

{//如果当前节点的左子树是运算符,且运算符优先级低于当前运算符,

〃那么左边的表达式要先计算,需要加括号

if(isOper(p->left->opcr)&&gctOpcrOrdcr(p・>lcft・>opcr)vgctOpcrOrdcr(p・>opcr))

{

cout«n(n;

inOrder(p->left);

cout«,i)M;

}

else//否则直接输岀左子树

inOrdcr(p->left);

coulvvp・>opcr;〃输出当前盯点

if(p->right)

{〃如果当前节点的右子树是运算符,且运算符优先级不髙于当前运算符,

〃那么右边的表达式要先计算,需要加括号

if(isOper(p->right->opcr)&&gctOpcrOrdcr(p・>righJ>opcr)v=gctOpcrOrdcr(p〉opcr)){

cout«H(n;

inOrder(p->right);

cout«,,)M;

}

else

inOrder(p->right);

}

}

voidpost2tree(TNode*&p,stringstr)//后缀表达式生成二叉树

{//(a)碰到操作数则把其值赋给相应的新申请的二叉树结点,若栈为空则地址压栈,

//(b)碰到操作符则把其值赋给相应的新申请的二叉树结点,取栈顶元素,

〃若当前元素的左孩子为空则设为其左孩子,

〃左孩子为满则设为其右孩子,开始那个元素地址为根结点地址,开始时用变量root保存。

stacknodeStack;//用于保存节点指针的栈

chartemp;

inti=0;

temp=str[i++];

whilc(tcmp!

=、(y)

{

if(temp!

=\0,&&!

isOper(temp))//不是运算符,则进栈

{

p=newTNode(temp);//以temp为结点值构造二叉树结点nodeStack.push(p);

temp=str[i++]y/读入F—个

}

else

{〃如果遇到符号,则弹栈,依次设为右节点和左节点

p=newTNode(temp);

if(nodcStack.sizeO)

{

p->right=nodeStack.top();//若非空则弹栈并设为结点的右孩子

nodcStack.popO;

if(nodcStack.sizeO)

{p->left=nodcStack.top();〃若非空则禅栈并设为结点的左孩子

nodcStack.popO;

}

nodeStack.push(p);

temp=str[i++];

}

}

}

voidpre2tree(TNode*&p.stringstr)//前缀表达式生成二叉树

{//碰到操作数则把其值赋给相应的新申请的二叉树结点,地址压栈:

〃碰到操作符则把其值赋给相应的新申请的二叉树,并从栈中弹出两个地址,

〃分别作为其左指针和右指针,然后再把其地址压栈,最后一个地址即为二叉树的根结点地址。

stacknodeStack;

chartemp;

inti=str.size()-l;

temp=str[i-];

while(temp!

=f\Or)

{

if(temp!

=\0*&&JisOper(tenip))

{p=newTNode(temp)7/以temp为内容来建立新的结点

nodcStack.push(p);

temp=str[i-];}

else

{p=newTNode(temp);

if(nodeStack.size())//栈非空

{p->left=nodeStack.top();〃则栈顶指针所指结点设it成当前结点左孩子

nodcStack.popO;

}

if(nodcStack.sizc())〃栈非空

{p->right=nodeStack.top()7/则栈顶指针所指结点设置成当前结点右孩子

nodeStack.popO;〃栈顶元素左右孩子指针设置完毕弹岀

}

nodeStack.push(p);

temp=str[i-];

}

}〃当栈空且扫描到最后时,树根由P带回

voidin2tree(TNode*&p.stringstr)//中缀表达式转换成后缀表达式生成二叉树

stacka;

chartemp;

stringPostfixexp=,H,;

inti=0;

temp=str[i++];

whilc(icmp!

=、(K)

{

if(!

isOpcr(tcmp))〃操作数则宜接进数据栈

{Postfixexp+=temp;

temp=str[i++];

}

elseif(temp==,(,)//进栈

{

a.push(temp);temp=str|i++J;

}

elseif(temp=,)')

{

whilc(a」op()!

=()//脱括号

{

Postfixexp+=a.top();

a.pop();〃在碰到开括号和栈为空前反复弹岀栈中元素

}

a.popO;

temp=str[i++);

}

elseif(temp=,+,lltemp=-1ltemp==,*,lltemp==7)//出栈

{

while(!

a.empty()&&a.top()!

=C&&getOperOrder(a.top())>=getOperOrder(temp))

〃若栈非空栈顶不是左括号且栈顶元素优先级不低于输入运算符时,

//将栈顶元素弹岀到后缀表达式中,并且str下标加

{Postfixexp+=a.top();a.pop();}

a.push(temp);

temp=str[i++];

}

}//endwhile(temp!

=W)

while(!

a.einpty())

{Postfixexp+=a.top();

a.popO;

}

Postfixexp+=W\

//cout«Postfixexp:

post2tree(p.Postfixexp);

}

voidcount(TNode*pjnt&heightjntn)〃求值函数

{//求树的高度

if(p->left=NULL&&p->righl=NULL)

{if(n>height)

height=n;}

if(p->left!

=NULL)

count(p->left,height.n+l);

if(p->right!

=NULL)

count(p->right,height.n+1);

}

voidpaint(TNode水p)//打印树

{

intheight=O;

inth=0;

inti;

usingstd:

:

queue:

queueaQueue:

count(p,height」);

TNode*pointer=p;

TNode*lastpointer;

if(pointer)

{pointer->s=l;

pointer->t=l;

aQueue.push(pointer);}

while(!

aQueue.empty())

{lastpointer=pointer;

pointer=aQueue.front();

aQucue.popO;

if(pointer->s>h)

{cout«endl;

h=pointer->s;}

if(pointer->t==l)

{for(i=0;is)-1;i++)

cout«H”;}

elseif(lastpointer->s!

=pointer->s){

for(i=0;i<(pointer->t-1)*(pow(2,height-pointer->s+1)-1)+(pointer->t-1)-1+pow(2.height-pointer->s);i++)

cout«,rM;}

else

{for(i=0;i<(pointer->t-lastpointer->t)*(pow(2,height-pointer->s+1)-1)+(pointer->t-lastpointer->t)-l;i++)

cout«HH;}

cout«pointer->opcr;

if(pointer->left!

=NULL){

pointer->left->s=pointer->s+1;

pointer->left->t=pointer->t*2-l;

aQueue.push(pointer->Ieft);}

if(pointer->right!

=NULL){

pointer->right->s=pointer->s+1;pointer->right->t=pointer->t*2;

aQueue.push(pointer->right);

}}}

intmain()

{

stringexpression;

TNode*tree;

cout«"请输入表达式类型,前缀表达式输入-1,中缀表达式输入0后缀表达式输入lM«endl;

intflag;

cin»flag;

coutvv"请输入字符串表达式:

H«endl;

cin»expression:

if(flag=-l)//那么是前缀表达式

pre2tree(tree,expression);

elseif(flag==l)//那么是后缀表达式

post2tree(tree,expression);

else//否则中缀表达式

in2tree(tree,expression);

paint(trec);

cout«endl:

cout«"中缀表达式为:

“;

inOrder(tree);

cout«endl;

cout«"前缀表达式为:

“;

preOrder(tree);

cout«endl;

cout«"后缀表达式为:

";

postOrder(tree);

cout«endl;freeTree(tree);cout«endl;

return0;

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

当前位置:首页 > 初中教育 > 语文

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

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