折腾了好久终于把这个程序完善了。
二叉树的定义就不再啰嗦了。
这个程序注意的地方有如下几个:
1. 节点存储的可能是数,可能是符号,因此数据要做区分。
2. 操作符优先级,括号要特殊处理。
代码如下
Stack.h:
#ifndef STACK_H_
#define STACK_H_
#define STACK_INIT_SIZE 10
#define STACKINCREMENT 5
#ifndef Status
#define Status int
#define OK 1
#define ERROR 0
#define OVERFLOW 2
#endif
#include<cstdlib>
#include<malloc.h>
template<class sElemType>
class Stack
{
private:
sElemType* base;
sElemType* top;
int stacksize;
public:
Stack();
~Stack();
Status ClearStack();
bool StackEmpty();
int StackLength() { return stacksize; }
Status GetTop(sElemType & e);
Status Push(sElemType e);
Status Pop(sElemType & e);
Status StackTraverse(Status(*visit)(sElemType t));
};
template<class sElemType>
Stack<sElemType>::Stack()
{
base = (sElemType*)malloc(STACK_INIT_SIZE*sizeof(sElemType));
if (!base) exit(OVERFLOW);
top = base;
stacksize = STACK_INIT_SIZE;
}
template<class sElemType>
Status Stack<sElemType>::GetTop(sElemType & e)
{
if (top == base) return ERROR;
e = *(top - 1);
return OK;
}
template<class sElemType>
Status Stack<sElemType>::Push(sElemType e)
{
if (top - base >= stacksize)
{
base = (sElemType*)realloc(base, sizeof(sElemType)*(stacksize + STACKINCREMENT));
if (!base) exit(OVERFLOW);
top = base + STACKINCREMENT;
stacksize += STACKINCREMENT;
}
*top++ = e;
return OK;
}
template<class sElemType>
Status Stack<sElemType>::Pop(sElemType & e)
{
if (top == base) return ERROR;
e = *(--top);
return OK;
}
template<class sElemType>
Status Stack<sElemType>::ClearStack()
{
if (stacksize)
{
free(base);
base = NULL;
top = NULL;
stacksize = 0;
}
return OK;
}
template<class sElemType>
bool Stack<sElemType>::StackEmpty()
{
return top == base;
}
template<class sElemType>
Stack<sElemType>::~Stack()
{
ClearStack();
}
template<class sElemType>
Status Stack<sElemType>::StackTraverse(Status(*visit)(sElemType t))
{
for (int i = 0; i < stacksize; i++)
{
Status temp = visit(base[stacksize - i]);
if (temp == ERROR) return ERROR;
}
}
#endif
Expression_bitree.cpp
#include"Expression_bitree.h"
//工具函数
int get_priority(char t)
{
switch(t)
{
case '(':return 4;
case ')':return 1;
case '+':return 2;
case '-':return 2;
case '*':return 3;
case '/':return 3;
}
}
char priority(char a, char b)
{
if (get_priority(a) > get_priority(b))
return '>';
else if (get_priority(a) == get_priority(b))
return '=';
else return '<' ;
}
Status ReadNumber(char* & item, int & num)
{
Stack <char>temp;
int power = 1;
num = 0;
if (!item)
return ERROR;
while (isdigit(*item))
{
temp.Push(*item);
item++;
}
while (!temp.StackEmpty())
{
char tempchar;
if (!temp.Pop(tempchar)) return ERROR;
num += power * (tempchar - 48);
power *= 10;
}
return OK;
}
Status CreateBiTree(BiTree & T, int item)
{
if (T != NULL)
return ERROR;
else
{
if (!(T = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
{
T->data.ischar = false;
T->data.data = item;
T->lchild = NULL;
T->rchild = NULL;
}
}
return OK;
}
Status CreateBiTree(BiTree & T, char item)
{
if (T != NULL)
return ERROR;
else
{
if (!(T = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
{
T->data.ischar = true;
T->data.data = item;
T->lchild = NULL;
T->rchild = NULL;
}
}
return OK;
}
//接口函数
Status CreateBiTree(BiTree & T, char* item)
{
//检查T为空,item非空
if (!item)
return ERROR;
if (T)
return ERROR;
//检查是否已经到了字符串尾
if (!(*item)) return OK;
//申请内存空间,指针置空
if (!(T = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
T->lchild = NULL;
T->rchild = NULL;
//申请操作符栈,树栈
Stack <char>operator_stack;
Stack <BiTree>tree_stack;
//如果有括号,优先进行括号操作
while (*item)
{
//判断是不是数
char* tempItem = item;
int num;
if (isdigit(*item))
{
ReadNumber(item, num);
BiTree tempTree = NULL;
CreateBiTree(tempTree, num);
tree_stack.Push(tempTree);
}
//如果不是数那就是操作符了
else
{
//栈空,则压入
if (operator_stack.StackEmpty())
{
operator_stack.Push(*item);
item++;
}
//栈非空,则比较优先级
else
{
char tempChara;
operator_stack.GetTop(tempChara);
switch (priority(*item, tempChara))
{
case '>': {
operator_stack.Push(*item);
item++;
break;
}
case '=':
{
}
case '<':
{
//对括号单独处理
if (*item == ')')
{
char tempChar;
operator_stack.Pop(tempChar);
while (tempChar != '(')
{
BiTree tempTree = NULL;
BiTree tempTree2;
if (!(tempTree = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
tree_stack.Pop(tempTree2);
tempTree->data.ischar = true;
tempTree->data.data = tempChar;
tempTree->lchild = tempTree2;
tree_stack.Pop(tempTree2);
tempTree->rchild = tempTree2;
tree_stack.Push(tempTree);
operator_stack.Pop(tempChar);
}
item++;
}
else
{
char m = *item;
while (priority(*item, m)!='>'&&(tempChara != '(')&&!operator_stack.StackEmpty())
{
BiTree tempTree = NULL;
BiTree tempTree2;
char tempChar;
if (!(tempTree = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
tempTree->data.ischar = true;
operator_stack.Pop(tempChar);
tempTree->data.data = tempChar;
tree_stack.Pop(tempTree2);
tempTree->lchild = tempTree2;
tree_stack.Pop(tempTree2);
tempTree->rchild = tempTree2;
tree_stack.Push(tempTree);
operator_stack.GetTop(m);
}
operator_stack.Push(*item);
item++;
}
}
break;
}
}
}
}
std::cout << "t\n";
while (!operator_stack.StackEmpty())
{
BiTree tempTree = NULL;
BiTree tempTree2;
char tempChar;
if (!(tempTree = (BiTNode*)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
tempTree->data.ischar = true;
operator_stack.Pop(tempChar);
tempTree->data.data = tempChar;
tree_stack.Pop(tempTree2);
tempTree->lchild = tempTree2;
tree_stack.Pop(tempTree2);
tempTree->rchild = tempTree2;
tree_stack.Push(tempTree);
}
tree_stack.Pop(T);
}
Status PreOrderTraverse(BiTree & T, Status(*visit)(Data e))
{
if (T)
{
if (visit(T->data))
{
if (PreOrderTraverse(T->lchild, visit))
if (PreOrderTraverse(T->rchild, visit)) return OK;
return ERROR;
}
}
else
{
return OK;
}
}
Expression_bitree.h
#ifndef EXPRESSION_BITREE_H_
#define EXPRESSION_BITREE_H_
#include"Stack.h"
#include<cctype>
#include<iostream>
typedef struct Data {
bool ischar;
int data;
};
typedef struct BiTNode {
Data data;
struct BiTNode * lchild, *rchild;
} *BiTree;
Status CreateBiTree(BiTree & T, char* item);
Status PreOrderTraverse(BiTree & T, Status(*visit)(Data e));
#endif
main.cpp
#include"Expression_bitree.h"
Status print(Data i)
{
using namespace std;
if (i.ischar)
cout << (char)i.data;
else
cout << i.data;
system("pause");
return OK;
}
int main()
{
using namespace std;
BiTree pine = NULL;
CreateBiTree(pine, "1+2*(3-4)-5/6");
cout << "create finished" << endl;
system("pause");
PreOrderTraverse(pine, print);
system("pause");
}