#include < iostream >
using namespace std;
#define NUM 100
typedef struct Node
{
char data;
struct Node *lchild,*rchild;
}TreeNode,*pTreeNode;
typedef struct
{
pTreeNode *elem[NUM]; // 存的是结点的 “位置 ”,故用指针
int top;
int stacksize;
}Stack;
void initStack(Stack &s)
{
s.top = -1;
s.stacksize = NUM;
}
// 判断栈满
int stackFull(Stack s)
{
if(s.top == s.stacksize-1)
return 1;
return 0;
}
// 判断栈空
int emptyStack(Stack s)
{
if(s.top == -1)
return 1;
return 0;
}
// 入栈(进栈的是结点位置)
void push(Stack &s,pTreeNode *e)
{
if(stackFull(s))
return;
s.elem[++s.top] = e;
}
// 出栈
void pop(Stack &s,pTreeNode *&e)
{
if(emptyStack(s))
return;
e = s.elem[s.top--];
}
// 先序创建二叉树
pTreeNode createTree(char *str) // 接受一个字符串
{
Stack s;
initStack(s); // 建栈
pTreeNode T, pre; // 二叉树的结点
pTreeNode *p; // 用于保存二叉树的结点位置
int popflag = 0; // 返回的是右结点的标志
if(str[0]!='#'){ // 根结点不为空,创建根结点
T = new TreeNode;
T->data = str[0];
T->lchild = T->rchild = NULL;
push(s, &T->rchild); // 将T指向的右孩子的位置压栈
pre = T;
}
else
return NULL; // 否则返回空
int i=1;
while(str[i]!='\0' || !emptyStack(s)){ // 先序序列的字符没有读完 或 栈不为空,即树还未创建完
if(str[i]!='#'){ // 字符没有读完,且不为空
pTreeNode np = new TreeNode; // 新建一个结点
np->data = str[i];
np->lchild = np->rchild = NULL;
if(popflag){ // 如果是出栈的右孩子的
*p = np; // 原先右孩子的位置赋予新结点的值
popflag = 0;
}
else
pre->lchild = np; // if..else 都是连入树的操作
push(s, &np->rchild); // 将新结点的右孩子的位置压栈
pre = np;
}
else if(str[i]=='#'){
pop(s,p);
popflag = 1; // 接下来一个是右孩子位置
}
i++; // 检测下一个字符
}
return T;
}
void preOrder(pTreeNode pt)
{
if(pt)
{
cout<<pt->data;
preOrder(pt->lchild);
preOrder(pt->rchild);
}
else
cout<<'#';
}
int main()
{
char *a = "ABC##DE#G##F###"; // 先序遍历得到的字符序列,包括空的孩子指针
pTreeNode pt = createTree(a); // 创建,关键函数
preOrder(pt);
cout<<endl;
return 0;
}