无微不至带你学 ------>C & C++ / <数据结构> / 表达式树

大家好,我是 DongGu ,是一名软件工程专业大二的学生,写博客一方面是为了记录自己的学习过程,把自己犯的错误进行分享。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!有任何问题可以评论或者QQ联系(1521839703)


#FFD700


运行结果

直接看看成果
在这里插入图片描述


注意事项 (有几个判断是让人忽略的!!)

  1. 因为你构造的是表达式树 , 所以一个运算符一定有两个“儿子”,

  2. 还要判断最后返回的栈,是不是就只有有一个,这里要检查一下,毕竟在生活中用户才不管合不合法,就是玩…

    例如 a b c + ;
    它最后还留了个a 在栈S里

  3. 在输出的时候,我们可以尝试输出括号,比如(a + b * c) ,其实是(a + b)* c括号优先级高一点 防止加减乘除的优先级顺序, 所以加上括号,左子树一对, 右子树一对

  4. 剩下的中序,前序,后序的,就不多讲了,毕竟都已经学到这了

  5. 最后还想聊聊 大家对空指针的理解,一开始我以为它是不能赋值的,后面才知道可以,毕竟它是个指针变量,举个例子

    int *p = NULL;
    int a = 4;
    p = &a;
    cout << *p; // -------> 输出3;

  6. 在这里采用不同的头文件来编写,这样利于管理,易懂

    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;
}

计划

  • 接下来一个几个月将会记录我数据结构的学习总结和数据库方面 , 尽量弄成大专题 包含 若干小分类,节省大家时间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DongGu.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值