UVA 112 Tree Summing

二叉树基础题

1. 去空格  2.由括号表达式建树(用两个栈)  3.搜索

此题先是参考了下别人的代码,算是基础的练习+复习。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn = 10000;

struct Node
{
	int data;
    Node *left, *right;
};
char stackch[maxn]; //字符栈 
char s[maxn];
Node *stack[maxn]; //结点栈 
int topc, topn, ok;                                       
int count1, count2, countc;  //很奇怪声明count会出错,声明countc不会 

void init()
{
	topn = 0;topc = 0; ok = 0;
	memset( stackch , 0 , sizeof( stackch ) );
    memset( stack , 0 , sizeof( stack ) ) ;
    memset( s , 0 , sizeof( s ) ) ;    //s[maxn]一定要清0,否则会RE。因为不清0,仅仅覆盖,会导致下组数据strlen(s)出错 
	//count1 = 0; count2 = 0; countc = 0;
	return ;
}
void inputdata()  //读入数据 
{
    int count1 = 0, count2 = 0, countc = 0;
	int flag = 0;
	while (1)
	{
		char ch = getchar();
		if (ch == '(')
		{
			flag = 1;
			count1++;
			s[countc++] = ch;
		}
		if (isdigit(ch) || ch == '-')
		{
			s[countc++] = ch;
		}
		if (ch == ')')
		{
			count2++;
			s[countc++] = ch;
		}

		if (count1 == count2 && flag)break;  //并不是以回车符作为输入结束的判断
		//如果前括号与后括号的数量相同,并且进入过括号,读入数据结束  
	}
	return ;
}
void change(char t[], int len) //数组名做函数形参,传递的是数组的首地址,相当于址传递。这点与变量做形参不同 P146
{
	char ts[1000];
	int j = 0;
	for (int k = len-1; k >= 0; k--)
	{
		ts[j++] = t[k]; 
	}
	strcpy(t,ts);
	t[j] = '\0';  //注意strcpy()拷贝字符串,直到发现'\0'字符串结束符才结束,但并没拷贝结束符。没有这句话会RE。 
	return ;
}

Node *addNode(int data, Node *left, Node *right) //添加结点 
{
	Node *father = new Node;
	father->data = data;
	father->left = left;
	father->right = right;
	return father;
}
void buildTree()  //建树 
{
	int len = strlen(s);
	for (int i = 0; i < len; i++)
	{
		if (s[i] == ')')  //当遇到后括号时,找前一个前括号,并且创建结点入栈
		{
			char node[1000];
			int c = 0;
			//memset( node , 0 , sizeof( node ) ) ;
			while (stackch[topc] != '(')
			{
				node[c++] = stackch[topc--];
			}
			topc--;
			change(node,c);
			int num = (int)atof(node);
			if (strlen(node))
			{
				Node *right = stack[topn--];   //先right后left的顺序是固定的 
				Node *left = stack[topn--];
				Node *father = addNode(num, left, right);
				stack[++topn] = father;    //注意是++topn不是topn++ 
			}
			else 
			{
				Node *p = new Node;      //如果是空结点(前括号与后括号相邻),创建空结点。这个一定要有 
				p = NULL;
				stack[++topn] = p; 
			}
		}
		else 
		{
			stackch[++topc] = s[i];  //不是后括号,入字符栈
		}
	}
}

void dfs(int ans, int cur, Node *u)
{
	if (u != NULL)//当结点不为空 
	{
		cur += u->data;
		//当到达树的最底部,并且和与ans相等,说明找到答案
		if (ans == cur && !(u->left) && !(u->right))
		{
			ok = 1;
			return ;
		}
		else 
		{
			if (u->left) {dfs(ans, cur, u->left);} //递归左子树 
			if (u->right){dfs(ans, cur, u->right);} //递归右子树 
		}
	}
}
int main()
{
	int ans;
	while (scanf("%d",&ans) == 1)
	{
		init();
		inputdata();
		buildTree();
		Node *root = stack[topn];  //树根是结点栈顶部的元素
		dfs(ans, 0, root);
		if (ok)
		{
			printf("yes\n");
		}
		else 
		{
			printf("no\n");
		}
	}

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值