数据结构实验 二叉树实验(括号表示法的合法性检查)

数据结构实验课之二叉树实验(一)

该博客待完善,编者目前为大二学生水平较差,内容仅供参考

实验内容:

以括号表示法作为输入字符串构造一棵二叉树,完成下列实验要求:

(1)如果输入字符串不符合规范,显示错误信息:“输入错误”。

(2)分别显示该二叉树的先序、中序和后序遍历。

(3)求出该二叉树的高度。

(4)输出该二叉树所有的叶子结点。

(5)找出二叉树中的最大、最小值结点,并写出他们的所在层数

 

令人心碎,其中(2)(3)(4)(5)教材上都有对应类似代码实现起来并不难,个人觉得难点主要在(1)中检查输入是否合法,即括号表示法合法性检查这一块内容。

我一共想到了以下几种非法输入(因个人能力有限,肯定还有没想到的点,希望大家能指正包含)。

1.一对括号中逗号数超过两个,例如A(B,C,D) ,非法

2. 形如 (B,C) 即在第一个左括号前少一个字符,非法

3.形如AA(B,C) ,即数据超过一个字符,非法。  注:本例中我默认数据元素只有一个字符

4.形如 A())   A)))(((   ,类似左右括号不匹配,非法。

5.形如A(B,C)D ,类似错误

实现代码如下

#include<bits/stdc++.h>
#define Max 100000 
using namespace std;
char Tmax;//最大值节点
char Tmin;//最小值节点 
int k1,k2;
struct node
{
	char data;
	node * lchild;
	node * rchild;
};

bool CreateBTree(node * &b,string str)
{
	stack<char>q; //判断输入合法性用的栈 
	bool flag=true;//是否合法标记 
	//bool zm=true;// 输入节点名之后一定要跟一个左括号  如:AA非法 
	//bool jm=false;//在左括号前是否缺少节点元素判断  如:(A,B) 非法 。false表示还未输入数据元素,true表示已输入节点元素 
	node *St[Max],*p;
	int top=-1,k,j=0;
	int Dnum=0;//逗号数量 
	char ch;
	b=NULL;
	ch=str[j];
	while(ch!='\0' && flag)
	{
		switch(ch)
		{
			case '(':
				//if(!jm)flag=false; 
				//jm=false;//输入左括号后一定要跟一个节点元素  A(B,C)
				if(q.empty()){cout<<"左括号前缺少数据元素"<<endl;flag=false;break;}//如果栈为空,即左括号前没有数据元素时,非法输入				 
				top++;
				St[top]=p;
				k=1;
				q.push(ch);
				Dnum=0;//输入右括号后逗号数初始化0 
				break;
			case ')':
				//cout<<"test1"<<endl;
				//if(q.empty())cout<<'1'<<endl;
				top--;
				while(!q.empty() && q.top()!='(')
				{
					if(q.top()==',' && Dnum>0)Dnum--; 
					q.pop();
				}	
				if(q.empty())    //在获取栈顶元素前一定要判断栈是否为空,如果为空强行获取栈顶元素程序会报错 
				{
					flag=false;
					cout<<"左右括号不匹配"<<endl; 
					break;	
				} 
				else if(q.top()=='(')
				{
					q.pop();
				}
				break;
			case ',':
				k=2;
				Dnum++;
				q.push(ch);
				if(Dnum>=2)
				{
					flag=false;
					cout<<"逗号数量大于1个"<<endl;
				}
				break;
			default:  
					p=new node;
					p->data=ch;
					p->lchild=p->rchild=NULL;
					if(q.empty() ||  q.top()=='(' || q.top()==','||ch==',')//如果栈为空或者栈顶元素为'('将数据元素入栈 
					{
						q.push(ch);
					}
					else //否则非法 
					{
						flag=false;
						cout<<"数据元素输入过多(数据元素只允许一个字符)或某数据元素前一个字符不是左括号"<<endl;
						//cout<<"test4"<<endl;
						//cout<<q.top()<<endl;//test
						//cout<<ch<<endl;//test 
						break;
					}
					if(b==NULL)
						b=p;
					else
					{
						switch(k)
						{
								case 1:St[top]->lchild=p;break;
								case 2:St[top]->rchild=p;break;
						}
					}
		}
		
		if(flag==false)
		{
			//cout<<"输入不合法,括号失配"<<endl;
			return flag;
		}
		j++;
		ch=str[j];
					
	}
	if(q.size()!=1)
	{
		flag=false;
		cout<<"栈剩余元素大于1,左右括号匹配失败或其他未满足格式情况"<<endl; 
		//int tmp=q.size(); test
		//cout<<tmp<<endl;
	}
	return flag;
}

void PreOrder(node *b)//先序遍历 
{
	if(b!=NULL)
	{
		cout<<b->data<<' ';
		PreOrder(b->lchild);
		PreOrder(b->rchild);
	}
}

void InOrder(node *b)//中序遍历 
{
	if(b!=NULL)
	{
		InOrder(b->lchild);
		cout<<b->data<<' ';
		InOrder(b->rchild);
	
	}
}

void PostOrder(node *b)//后序遍历 
{
	if(b!=NULL)
	{
		PostOrder(b->lchild);
		PostOrder(b->rchild);
		cout<<b->data<<' ';
	}
}

int BTHeight(node *b)//获得树高度的函数 
{
	int lchildh,rchildh;
	if(b==NULL)return 0;
	else
	{
		lchildh=BTHeight(b->lchild);
		rchildh=BTHeight(b->rchild);
		return (lchildh>rchildh)?(lchildh+1):(rchildh+1);
	}
}

void Dischild(node *b)//输出叶子节点 
{
	if(b!=NULL)
	{
		if(b->lchild==NULL && b->rchild ==NULL)
			cout<<b->data<<' ';
		Dischild(b->lchild);
		Dischild(b->rchild);	
	}
}

void getMaxMin(node *b,int k)
{
	if(b==NULL)  //空树直接返回 
		return ;
	else
	{
		char temp=b->data ;
		k++;
		if(temp>Tmax){Tmax=temp;k1=k;}
		if(temp<Tmin){Tmin=temp;k2=k;}
		getMaxMin(b->lchild ,k);
		getMaxMin(b->rchild ,k);
	} 
	
}

int main()
{
	string s;
	bool flag;
	node *b;
	cin>>s; 
	while(!CreateBTree(b,s))
	{
		cout<<"输入错误"<<endl;
		cout<<endl; 
		flag=true;//合法标记重置 
		b=NULL;//指针重置 
		cin>>s;//重新输入括号表达式 
	}
	int height=BTHeight(b);
	
	cout<<"先序遍历:"<<endl; 
	PreOrder(b);
	cout<<endl;
	 
	cout<<"中序遍历:"<<endl;
	InOrder(b);
	cout<<endl;
	
	cout<<"后序遍历:"<<endl;
	PostOrder(b);
	cout<<endl;
	 
	cout<<"二叉树的高度为:"<<height<<endl;
	cout<<"二叉树的叶子节点为:";
	Dischild(b);
	cout<<endl;
	
	Tmax='0';
	Tmin='z'+1;
	getMaxMin(b,0);

	cout<<"最大值节点为:"<<Tmax<<" 其所在层数为:"<<k1<<endl;
	cout<<"最小值节点为:"<<Tmin<<" 其所在层数为:"<<k2<<endl;
		
	return 0;
}

测试结果图片

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值