这个真的写了好久,所以单独发一章
函数代码
bool CreateBiTree(BiTree& T) {
char ch; int flag = 0;//flag作为标记用,当flag=0时创建当前结点的左孩子,flag=1时创建当前结点的右孩子
cin >> ch;
if (ch == '#') {//如果根结点为空则创建结束
T = NULL;
return 1;
}
BiTree newnode = new BiTNode; //用来存储创建的新结点
BiTree temp = new BiTNode; //临时变量,用来存储出栈的值或者未出栈的栈顶值
BiTree temp1 = new BiTNode;//当需要同时用到出栈值和未出栈的栈顶值时作为第二个临时变量
if (!newnode || !temp || !temp1)return 0;
LinkStack S; InitStack(S);
T = new BiTNode;
T->data = ch;
T->lchild = NULL; T->rchild = NULL;//先为根结点赋值
Push(S, T);//将根结点压入栈
while (1) {
cin >> ch;
if (ch == '#' && flag == 0) {
//需要创建左子树的头结点且值为空,令当前结点的左孩子等于NULL,转为创建右子树头结点,flag=1
GetTop(S, temp);
temp->lchild = NULL;
flag = 1;
}
else if (ch == '#' && flag == 1) {
//需要创建右子树的头结点且值为空,表明当前结点的左右孩子已创建完成,令当前结点的右孩子等于NULL
Pop(S, temp);
GetTop(S, temp1);
temp->rchild = NULL;
//将栈顶元素(即当前元素)出栈,当前元素与新的栈顶元素进行比较
//,若新的栈顶元素的右孩子与当前元素相同,则说明当前结点的父结点左右孩子同样创建完成,
//继续进行这一操作直到栈顶元素的右孩子与出栈元素不相同
while (temp1->rchild == temp) {
Pop(S, temp);
if (!GetTop(S, temp1))return 1;
//若栈空无法取得栈顶元素,说明新输入的值为二叉树的最右结点,二叉树建立完成
}
}
else {
newnode = new BiTNode;
newnode->data = ch;//若输入值非#,则需要创建新结点
if (flag == 0) {//flag为0,建立左子树的头结点,下次创建为左子树头结点的左子树头结点因此flag无需更改
GetTop(S, temp);
temp->lchild = newnode;
Push(S, newnode);//中间经历结点压入栈中
}
else {//flag为1,建立右子树的头结点,下次创建为右子树头结点的左子树头结点,因此flag=0
GetTop(S, temp);
temp->rchild = newnode;
Push(S, newnode);//中间经历结点压入栈中
flag = 0;
}
}
}
return 1;
}
测试程序整体代码
#include <iostream>
using namespace std;
typedef char TElemType;
typedef struct BiTNode {
TElemType data;
struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;//二叉树
typedef BiTree SElemType;
typedef struct StackNode {
SElemType data;
struct StackNode* next;
}StackNode, * LinkStack;//栈
//栈的基本操作
bool InitStack(LinkStack& S);//初始化链栈
bool Push(LinkStack& S, SElemType e);//将元素e压入栈中
bool Pop(LinkStack& S, SElemType& e);//将首元素出栈,用元素e返回
bool StackEmpty(LinkStack S);//判断链栈是否为空
bool GetTop(LinkStack S, SElemType& e);//取链栈栈顶元素,用元素e返回
//二叉树的基本操作
bool CreateBiTree(BiTree& T);
bool Preorder(BiTree T);
bool Inorder(BiTree T);
bool Postorder(BiTree T);
bool CreateBiTree(BiTree& T) {
char ch; int flag = 0;//flag作为标记用,当flag=0时创建当前结点的左孩子,flag=1时创建当前结点的右孩子
cin >> ch;
if (ch == '#') {//如果根结点为空则创建结束
T = NULL;
return 1;
}
BiTree newnode = new BiTNode; //用来存储创建的新结点
BiTree temp = new BiTNode; //临时变量,用来存储出栈的值或者未出栈的栈顶值
BiTree temp1 = new BiTNode;//当需要同时用到出栈值和未出栈的栈顶值时作为第二个临时变量
if (!newnode || !temp || !temp1)return 0;
LinkStack S; InitStack(S);
T = new BiTNode;
T->data = ch;
T->lchild = NULL; T->rchild = NULL;//先为根结点赋值
Push(S, T);//将根结点压入栈
while (1) {
cin >> ch;
if (ch == '#' && flag == 0) {
//需要创建左子树的头结点且值为空,令当前结点的左孩子等于NULL,转为创建右子树头结点,flag=1
GetTop(S, temp);
temp->lchild = NULL;
flag = 1;
}
else if (ch == '#' && flag == 1) {
//需要创建右子树的头结点且值为空,表明当前结点的左右孩子已创建完成,令当前结点的右孩子等于NULL
Pop(S, temp);
GetTop(S, temp1);
temp->rchild = NULL;
//将栈顶元素(即当前元素)出栈,当前元素与新的栈顶元素进行比较
//,若新的栈顶元素的右孩子与当前元素相同,则说明当前结点的父结点左右孩子同样创建完成,
//继续进行这一操作直到栈顶元素的右孩子与出栈元素不相同
while (temp1->rchild == temp) {
Pop(S, temp);
if (!GetTop(S, temp1))return 1;
//若栈空无法取得栈顶元素,说明新输入的值为二叉树的最右结点,二叉树建立完成
}
}
else {
newnode = new BiTNode;
newnode->data = ch;//若输入值非#,则需要创建新结点
if (flag == 0) {//flag为0,建立左子树的头结点,下次创建为左子树头结点的左子树头结点因此flag无需更改
GetTop(S, temp);
temp->lchild = newnode;
Push(S, newnode);//中间经历结点压入栈中
}
else {//flag为1,建立右子树的头结点,下次创建为右子树头结点的左子树头结点,因此flag=0
GetTop(S, temp);
temp->rchild = newnode;
Push(S, newnode);//中间经历结点压入栈中
flag = 0;
}
}
}
return 1;
}
int main()
{
BiTree T, T1;
cout << "先序建立一个二叉树,输入先序序列,空用#代替:\n";
CreateBiTree(T);//先序建立二叉树;
cout << "先序遍历:";
Preorder(T);//先序遍历
cout << endl;
cout << "中序遍历:";
Inorder(T);//中序遍历
cout << endl;
cout << "后序遍历:";
Postorder(T);//后序遍历
cout << endl;
return 0;
}
bool Preorder(BiTree T) {
if (T) {
cout << T->data << " ";
Preorder(T->lchild);
Preorder(T->rchild);
return 1;
}
return 0;
}
bool Inorder(BiTree T) {
if (T) {
Inorder(T->lchild);
cout << T->data << " ";
Inorder(T->rchild);
return 1;
}
return 0;
}
bool Postorder(BiTree T) {
if (T) {
Postorder(T->lchild);
Postorder(T->rchild);
cout << T->data << " ";
return 1;
}
return 0;
}
bool InitStack(LinkStack& S) {
S = NULL;
return 1;
}
bool Push(LinkStack& S, SElemType e) {
StackNode* temp = new StackNode;
if (!temp)return 0;
temp->data = e;
temp->next = S;
S = temp;
return 1;
}
bool Pop(LinkStack& S, SElemType& e) {
if (S == NULL)return 0;
StackNode* temp = S;
e = S->data;
S = S->next;
delete temp;
return 1;
}
bool StackEmpty(LinkStack S) {
if (S == NULL)
return 1;
return 0;
}
bool GetTop(LinkStack S, SElemType& e) {
if (S == NULL)return 0;
e = S->data;
return 1;
}