大家好,我是 DongGu ,是一名软件工程专业大二的学生,写博客一方面是为了记录自己的学习过程,把自己犯的错误进行分享。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!有任何问题可以评论或者QQ联系(1521839703)
#FFD700
运行结果
直接看看成果
注意事项 (有几个判断是让人忽略的!!)
-
因为你构造的是表达式树 , 所以一个运算符一定有两个“儿子”,
-
还要判断最后返回的栈,是不是就只有有一个,这里要检查一下,毕竟在生活中用户才不管合不合法,就是玩…
例如 a b c + ;
它最后还留了个a 在栈S里 -
在输出的时候,我们可以尝试输出括号,比如(a + b * c) ,其实是(a + b)* c括号优先级高一点 防止加减乘除的优先级顺序, 所以加上括号,左子树一对, 右子树一对
-
剩下的中序,前序,后序的,就不多讲了,毕竟都已经学到这了
-
最后还想聊聊 大家对空指针的理解,一开始我以为它是不能赋值的,后面才知道可以,毕竟它是个指针变量,举个例子
int *p = NULL;
int a = 4;
p = &a;
cout << *p; // -------> 输出3; -
在这里采用不同的头文件来编写,这样利于管理,易懂
stack : 存放的是 树的根
tree: 存放的树的信息(data, 左树, 右树)
tree.h : 树的声明
tree.cpp: 相关函数的实现
stack.h, stack.cpp 同上
代码分成
exptree.h
#pragma once
#include<iostream>
using std::cout;
using std::cin;
typedef struct ExpTree Tree;
typedef Tree* PTree;
struct ExpTree
{
char data;
PTree left;
PTree right;
};
PTree CreatExpTree();
void InTraver(PTree T);
exptree.cpp
#include "exptree.h"
#include "stack.h"
PTree CreatExpTree()
{
char data;
Pstack S = CreatStack(); // 这里的栈 存的是 地址
if (S == NULL)
{
return NULL;
}
cout << "请输入: (Ctrl ^z 结束读入)\n";
while (cin >> data)
{
PTree temp = (PTree)malloc(sizeof(Tree));
if (temp == NULL)
{
cout << "内存超限\n";
return NULL;
}
if ('a' <= data && data <= 'z') {
temp->data = data;
temp->left = temp->right = NULL;
Push(S, temp);
}
else {
temp->data = data;
temp->right = Pop(S); // return tree;
// 因为你构造的是表达式树 , 所以一个运算符一定有两个“儿子”, 在这里还是给大家判断一下
if (S->next == NULL)
{
cout << "输入有误,构造不了表达式\n";
return NULL;
}
temp->left = Pop(S);
Push(S, temp);
}
}
// 例如 a b c + ;
// 它最后还留了个a 在栈S里
PTree ans = Pop(S);
if (is_empty(S)) return ans;
else
{
cout << "还有数据在栈里, 输入有误,构造不了表达式\n";
return NULL;
}
}
void InTraver(PTree T)
{
if (T == NULL) return;
/*
* 括号优先级高一点 防止加减乘除的优先级顺序
* 所以加上括号,左子树一对, 右子树一对
*/
if (T->left) cout << "( ";
InTraver(T->left);
cout << T->data << " ";
InTraver(T->right);
if (T->right) cout << ") ";
}
stack.h
#pragma once
#include"exptree.h"
typedef struct StackNode stack;
typedef stack* Pstack;
struct StackNode
{
PTree data;
Pstack next;
};
Pstack CreatStack();
PTree Pop(Pstack P);
int is_empty(Pstack P);
void Push(Pstack P, PTree T);
stack.cpp
#include "stack.h"
Pstack CreatStack()
{
Pstack S = (Pstack)malloc(sizeof(stack));
if (S == NULL) return NULL;
S->next = NULL;
return S;
}
int is_empty(Pstack P)
{
if (P->next == NULL) return 1;
else return 0;
}
void Push(Pstack P, PTree T)
{
Pstack temp = (Pstack)malloc(sizeof(stack));
temp->data = T;
temp->next = P->next;
P->next = temp;
}
PTree Pop(Pstack P)
{
PTree T = (PTree)malloc(sizeof(Tree));
Pstack temp = (Pstack)malloc(sizeof(stack));
// 就算是空指针, 也可以给它赋个地址, 因为它还是指针变量
// 所以就不用取判断它是否为空
temp = P->next;
T->data = temp->data->data;
T->left = temp->data->left;
T->right = temp->data->right;
P->next = temp->next;
free(temp);
return T;
}
main.cpp
#include "stack.h"
int main()
{
PTree TREE = CreatExpTree();
if (TREE == NULL)
{
return 0;
}
// 后序 前序代码相差不大, 懒得写了.....
cout << "中序遍历(中缀表达式):" << " \n";
InTraver(TREE);
return 0;
}
计划
- 接下来一个几个月将会记录我数据结构的学习总结和数据库方面 , 尽量弄成大专题 包含 若干小分类,节省大家时间