主函数
/ main.cpp
// 数据结构第二次上机
//
// Created by tao on 2017/3/30.
// Copyright © 2017年 tao. All rights reserved.
//
#include <iostream>
#include "LinStack.h"
#include <mm_malloc.h>
#include <ctype.h>
#include <stdlib.h>
#include "BiTree.h"
#include <stack>
#include <queue>
using namespace std;
typedef double DataType;
//判断是否为符号
int isoperator(char op)
{
switch(op)
{
case '+':
case '-':
case '*':
case '/':
return 1;
default :
return 0;
}
}
//判断运算符号优先级
int priority(char op)
{
if(op == '+'||op == '-')
return 1;
if(op == '*'||op == '/')
return 2;
if(op == '(')
return 0;
if (op == '#')
return -1;
return 0;
}
//把中缀表达式转换为后缀表达式
//strPost[]数组存放后缀表达式,strInfix[]存放中缀表达式
void postfix(char strPost[],char strInfix[])
{
DataType x=0;
int i=0,j=0;
LSNode *head;
StackInitiate(&head);
StackPush(head, '#');//初始化后将栈顶元素置为#
for(i = 0;strInfix[i] != '#';i++)
{
if((strInfix[i]>='0' && strInfix[i] <='9')||strInfix[i] =='.')
//如果这个是数字的话,就直接把中缀中这个元素写到后缀里
{
strPost[j++] = strInfix[i];
// strPost[j++] = ' ';
}
else
{
//strPost[j++] = ' ';
if(strInfix[i] == '(')//如果(,不用比较直接入栈
{
StackPush(head, strInfix[i]);
StackTop(head, &x);
// i++;
}
else if(strInfix[i] == ')')//如果是),不断退栈,直到找到与之对应的(
{
StackTop(head, &x);
while(x != '(')
{
strPost[j++] = ' ';
StackPop(head, &x);
//把x弹出之后写到这个后缀表达式中
strPost[j++]=x;
StackTop(head, &x);
//strPost[i++]=x;
}
StackPop(head, &x);//将与右括号对应的左括号退栈
StackTop(head, &x);
// strPost[j++]=strInfix[i];
}
//如果是除了左括号和右括号的操作符
else if(isoperator(strInfix[i]))
{
//先输入一个空格隔开操作数
strPost[j++] = ' ';
x = StackTop(head, &x);
while(priority(strInfix[i])<=priority(x))
// 当前的操作符小于等于栈顶操作符的优先级时,将栈顶操作符写入到后缀表达式,重复此过程
{
StackPop(head, &x);
// strPost[j++] = ' ';
strPost[j++]=x;
if(x==StackTop(head, &x))
StackPop(head, &x);
// strPost[j++]=x;
strPost[j++] = ' ';
StackTop(head, &x);
}
StackPush(head, strInfix[i]);// 当前操作符优先级大于栈顶操作符的优先级,将该操作符入栈
StackTop(head, &x);
}
}
}
x = StackTop(head, &x);
//一般这个时候栈里还有元素 直接弹出到后缀表达式
while (x!='#')
{
strPost[j++] = ' ';
strPost[j++]=StackPop(head, &x);
}
}
//读入数据函数
//把数字字符串转换成相应的数字
double numRead(char str[],int *i)
{
double x=0.0;
int k = 0;
while(str[*i] >='0' && str[*i]<='9') // 处理整数部分
{
x = x*10+(str[*i]-'0');
(*i)++;
}
if(str[*i]=='.') // 处理小数部分
{
(*i)++;
while(str[*i] >= '0'&&str[*i] <='9')
{
x = x * 10 + (str[*i]-'0');
(*i)++;
k++;//k来记录一共几个小数
}
}
while(k!=0)
{
x /= 10.0;//如果k=3,那就有3位小数,除以3次十
k--;
}
return x;
}
//后缀表达式转换成表达式树
void treeCreate(char poststr[])
{
stack<BiTreeNode*>s;//定义一个存放节点指针的栈
// stack<double>s1;//定义一个存放数字的栈
BiTreeNode *p = nullptr,*a,*b;
double x=0.0;
int i;
for(i = 0;poststr[i] != '#';i++)
{
Initiate(&p);
if((poststr[i]>='0' && poststr[i] <='9')||poststr[i] =='.')
{
//是数字的话,就把这个节点的数值存入,左孩子和右孩子都设成null,然后,压入存节点的栈
x = numRead(poststr, &i);
p->data = x;
p->leftChild = NULL;
p->rightChild = NULL;
s.push(p);//指针p进栈
// s.push(numRead(poststr,&i));
}
else if(isoperator(poststr[i]))
{
//新建节点p,分别表示她的左孩子和右孩子
Initiate(&a);
Initiate(&b);
a = s.top();
s.pop();
b = s.top();
s.pop();
p->data = poststr[i];
p->rightChild = a;
p->leftChild = b;
s.push(p);
}
else
continue;
}
//弹出节点
BiTreeNode *root = s.top();
s.pop();
PrintBiTree(root, 1);
}
//由后缀计算值
double post_calculate(char poststr[])
{
LSNode *head;
StackInitiate(&head);
int i=0;
DataType x = 0,x1 = 0,x2 = 0;
double a;
while (poststr[i] != '#')
{
if((poststr[i]>='0' && poststr[i] <='9')||poststr[i] =='.')
{
x = numRead(poststr, &i);
StackPush(head,x);
}
else if(poststr[i] == ' ')
i++;
else if(poststr[i] == '+')
{
StackPop(head, &x1);
StackPop(head, &x2);
StackPush(head, x1+x2);
StackTop(head, &x);
i++;
}
else if(poststr[i] == '-')
{
StackPop(head, &x1);
StackPop(head, &x2);
StackPush(head, x2-x1);
StackTop(head, &x);
i++;
}
else if(poststr[i] == '*')
{
StackPop(head, &x1);
StackPop(head, &x2);
StackPush(head, x1*x2);
StackTop(head, &x);
i++;
}
else if(poststr[i] == '/')
{
StackPop(head, &x1);
StackPop(head, &x2);
StackPush(head, x2/x1);
StackTop(head, &x);
i++;
}
}
a = StackTop(head, &x);
cout<<a<<endl;
return a;
}
int main(int argc, const char * argv[])
{
// int i;
//char str[512];// =" 3 4 + 5 * 6 - #";
//cout<<"后缀表达式是:"<<endl;
char str[512];
char post[512];
int ok = 1;
while(ok == 1)
{
printf("输入你想转换的中缀表达式哟,记得以井号键结束ヾ(=·ω·=)o\n");
scanf("%s",str);
postfix(post,str);
cout<<"这是转化后的后缀表达式(づ ̄3 ̄)づ╭❤~"<<endl;
cout<<post<<endl;
cout<<"呐~送你二叉树(๑•̀ㅂ•́)و✧\n"<<endl;
treeCreate(post);
cout<<"这是计算出来的值(づ。◕‿‿◕。)づ"<<endl;
post_calculate(post);
printf("你还想继续吗?按'1'继续,按'2'返回哦(·ェ·。)\n");
scanf("%d",&ok);
if (ok == 0)
{
cout<<"好了,这一切都结束了(ಥ_ಥ)"<<endl;
return 0;
}
}
二叉树头文件
//
// BiTree.h
// 数据结构第二次上机
//
// Created by tao on 2017/4/3.
// Copyright © 2017年 tao. All rights reserved.
//
#ifndef BiTree_h
#define BiTree_h
#endif /* BiTree_h */
typedef double DataType;
typedef struct Node
{
double data;
struct Node *leftChild;
struct Node *rightChild;
}BiTreeNode;
BiTreeNode* Initiate(BiTreeNode **root)
{
*root = (BiTreeNode *)malloc(sizeof(BiTreeNode));
(*root) -> leftChild = NULL;
(*root) -> rightChild = NULL;
return *root;
}
BiTreeNode *InsertLeftNode(BiTreeNode *curr,BiTreeNode *p)
{
DataType x;
BiTreeNode *s,*t;
if(curr == NULL) return NULL;
t = curr -> leftChild;
s = (BiTreeNode *)malloc(sizeof(BiTreeNode));
s -> data = x;
s -> leftChild = t;
s -> rightChild = NULL;
curr -> leftChild = s;
return curr->leftChild;
}
BiTreeNode *InsertRightNode(BiTreeNode *curr,BiTreeNode *p)
{
DataType x;
BiTreeNode *s,*t;
if(curr == NULL) return NULL;
t = curr -> rightChild;
s = (BiTreeNode *)malloc(sizeof(BiTreeNode));
s -> data = x;
s -> rightChild = t;
s -> leftChild = NULL;
curr -> rightChild = s;
return curr->rightChild;
}
void Destroy(BiTreeNode **root)
{
if((*root)!=NULL&&(*root)->leftChild!=NULL)
Destroy(&(*root)->leftChild);
if((*root)!=NULL&&(*root)->rightChild!=NULL)
Destroy(&(*root)->rightChild);
free(*root);
}
BiTreeNode *DeleteLeftTree(BiTreeNode *curr)
{
if(curr == NULL||curr->leftChild == NULL) return NULL;
Destroy(&curr -> leftChild);
curr->leftChild = NULL;
return curr;
}
BiTreeNode *DeleteRightTree(BiTreeNode *curr)
{
if(curr == NULL||curr->rightChild == NULL) return NULL;
Destroy(&curr -> rightChild);
curr->rightChild = NULL;
return curr;
}
void PreOrder(BiTreeNode *root,void visit(DataType item))
{
if(root != NULL)
{
visit(root->data);
PreOrder(root->leftChild,visit);
PreOrder(root->rightChild,visit);
}
}
void InOrder(BiTreeNode *root,void visit(DataType item))
{
if(root != NULL)
{
InOrder(root->leftChild,visit);
visit(root->data);
InOrder(root->rightChild,visit);
}
}
void PostOrder(BiTreeNode *root,void visit(DataType item))
{
if(root != NULL)
{
PostOrder(root->leftChild,visit);
PostOrder(root->rightChild,visit);
visit(root->data);
}
}
void PrintBiTree(BiTreeNode *root,int n)
{
int i;
char a;
if(root == NULL) return;
PrintBiTree(root->rightChild, n+1);
for(i = 0;i<n-1;i++)
printf(" ");
if (n>0)
{
printf("--- ");
if(root ->rightChild ==NULL && root ->leftChild ==NULL)
printf("%f\n",root->data);
else
{
a = (char)(root->data);
printf("%c\n",a);
}
}
PrintBiTree(root->leftChild,n+1);
}
}
链式栈头文件
//
// LinStack.h
// 数据结构第二次上机
//
// Created by 胡雨涛 on 2017/3/30.
// Copyright © 2017年 胡雨涛. All rights reserved.
//
typedef double DataType;
typedef struct snode
{
DataType data;
struct snode *next;
}LSNode;
void StackInitiate(LSNode **head)
{
*head = (LSNode *)malloc(sizeof(LSNode));
(*head)->next = NULL;
}
int StackNotEmpty(LSNode *head)
{
if(head -> next == NULL) return 0;
else return 1;
}
/*
void StackPush(LSNode *head,DataType x)
{
LSNode *p;
p = (LSNode *)malloc(sizeof(LSNode));
p->data = x;
p->next = head->next;
head->next = p;
}
*/
void StackPush(LSNode *head,DataType x)
{
LSNode *p;
p = (LSNode *)malloc(sizeof(LSNode));
p->data = x;
p->next = head->next;
head->next = p;
}
int StackPop(LSNode *head,DataType *d)
{
LSNode *p = head->next;
if(p==NULL)
{
printf("堆栈已空出错!");
return 0;
}
head->next = p->next;
*d = p->data;
free(p);
return *d;
}
int StackTop(LSNode *head,DataType *d)
{
LSNode *p = head->next;
if(p == NULL)
{
printf("堆栈已空出错!");
return 0;
}
*d = p->data;
return *d;
}
void Destroy(LSNode *head)
{
LSNode *p,*p1;
p = head;
while (p!=NULL)
{
p1=p;
p=p->next;
free(p1);
}
}