我正在开发一个项目,我必须在反向抛光表示法中使用表达式,将整数和运算符压入堆栈,然后在将它们插入二叉搜索树时将它们从堆栈中弹出。 / p>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
struct snode
{
int datum;
struct snode* bottom;
};
struct tnode
{
int datum;
struct tnode* left;
struct tnode*right;
};
struct snode*
push(struct snode* stack, int x) {
struct snode *S = (struct snode*)malloc(sizeof(struct snode));
S->datum = x;
S->bottom = stack;
return S;
}
struct snode* pop(struct snode* stack) {
struct snode *S;
if (stack == NULL)
return NULL;
S = stack->bottom;
free(stack);
return S;
}
int
peek(struct snode* stack){
return stack->datum;
}
struct tnode*
create_node(int x){
struct tnode* tmp;
tmp = (struct tnode*)malloc(sizeof(struct tnode));
tmp->datum = x;
tmp->right = NULL;
tmp->left = NULL;
return tmp;
}
void
print_table(struct tnode *AST){
if(AST !=NULL){
print_table(AST->left);
printf("%d ", AST->datum);
print_table(AST->right);
}
}
struct tnode*
build_tree(struct snode *S)
{
struct tnode* root;
if (S==NULL){
return NULL;
}else{
int top = peek(S);
if (top == 65 || top == 83 || top == 88 || top == 68 || top == 77){
return create_node(top);
}else{
root= create_node(top);
root->right = build_tree(pop(S));
root->left = build_tree(pop(S));
return root;
}
}
}
int
main(int argc, const char *argv[])
{
int i = 1;
struct tnode *tree = NULL;
struct snode *stack = NULL;
while (argv[i]!= NULL){
stack = push(stack, argv[i][0]);
i++;
}
tree = build_tree(stack);
print_table(tree);
return EXIT_SUCCESS;
}
我觉得这应该有效。一切都清洁干净。我通过说
来运行它./project 5 4 A
出来的是
135208 135224 135208 135240 135208 135224 135208 0 135208 135224 135208 52 0 53 0
什么时候应该
4 65 5
我认为这是因为我将元素推入堆栈的方式。
编辑:
我初始化了i,因此我= 1。
这是我得到的结果。
134480 134496 134480 0 5 4 5
EDIT2:
我决定摆脱atol(argv [i])并将其更改为argv [i] [0]。 见代码。
现在我的出局就是
65
答案 0 :(得分:0)
终于弄清楚发生了什么!
以下是新修改的部分,可让您的代码正常工作(请查看// <== EDIT
评论):
struct tnode*
build_tree(struct snode *S)
{
struct tnode* root;
if (S == NULL)
return NULL;
int top = peek(S);
if (top == 65 || top == 83 || top == 88 || top == 68 || top == 77)
{
root = create_node(top);
S = pop(S); // <== EDIT
root->right = build_tree(S);
S = pop(S); // <== EDIT
root->left = build_tree(S);
return root;
}
root= create_node(top);
return root;
}
int
main(int argc, const char *argv[])
{
int i = 1;
struct tnode *tree = NULL;
struct snode *stack = NULL;
int value = 0;
while (argv[i]!= NULL)
{
if ((value = atoi(argv[i])) == 0) // <== EDIT
value = argv[i][0];
stack = push(stack, value);
i++;
}
tree = build_tree(stack);
print_table(tree);
return EXIT_SUCCESS;
}
我注意到有3个问题导致了你的价值。
第一期:
您要查找的结果是4 65 5
,这意味着如果输入是数字(4,5等),则必须使用atoi()
的结果。如果输入不是数字,则必须使用ASCII值。
为此,我使用了以下几行:
if ((value = atoi(argv[i])) == 0) // <== EDIT
value = argv[i][0];
stack = push(stack, value);
在atoi()
的实施中,当转化失败时,atoi()
会返回0
。因此,我检查赋值的值:如果atoi()
返回0
,则使用ASCII值。
第二期:
你遇到的第二个问题是build_tree()
函数似乎有错误的逻辑。由于这是一棵树,我希望字符A
是根,数字4和5是分支,如下所示:
A
/ \
4 5
你的逻辑似乎扭转了局面,你的设置方式,数字成为根值,字母是分支。扭转你的逻辑解决了这个问题:
int top = peek(S);
if (top == 65 || top == 83 || top == 88 || top == 68 || top == 77)
{
root = create_node(top);
S = pop(S); // <== EDIT
root->right = build_tree(S);
S = pop(S); // <== EDIT
root->left = build_tree(S);
return root;
}
root= create_node(top);
return root;
上一期:
这是一个很大的问题。致电build_tree()
时,您会直接传递pop()
的结果。问题在于,您没有将新的根值影响到S
。因此:
第一次调用build_tree(pop(S))
时,最终会释放S
的内存空间。
稍后,当您第二次致电build_tree(pop(S))
时,您最终会在初始值(早期释放的值)上调用pop(S)
。
解决方案是在您致电S
时重新分配pop()
,然后再致电build_tree(S)
。
S = pop(S); // <== EDIT
root->right = build_tree(S);
S = pop(S); // <== EDIT
root->left = build_tree(S);
TL; DR: 我重新格式化了你的代码,现在应该解决这个问题。复制粘贴,你应该很好。