#数据结构
对题目的理解
利用递归可以更简便的写出创建代码,但是用栈更好理解。
之所以可以仅仅用一个先序序列创建二叉树是因为用#表示空结点的先序序列是唯一的,可以创建唯一二叉树。
利用栈后进先出的特点(LIFO),用链栈既可以建立连续的结点,又可以模仿遍历时的进退路线,从而建立一个二叉树。
代码
#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;//栈
//栈的基本操作
int InitStack(LinkStack& S);//初始化链栈
int Push(LinkStack& S, SElemType e);//将元素e压入栈中
int Pop(LinkStack& S, SElemType& e);//将首元素出栈,用元素e返回
int StackEmpty(LinkStack S);//判断链栈是否为空
int GetTop(LinkStack S, SElemType& e);//取链栈栈顶元素,用元素e返回
//二叉树的基本操作
int CreateBiTree(BiTree& T);
int Preorder(BiTree T);
int Inorder(BiTree T);
int Postorder(BiTree T);
int CreateBiTree(BiTree& T)
{
char ch;
cin >> ch;
T = new BiTNode;
int flag = 0;//flag等于0时遍历左节点,等于一时遍历右节点;
if (ch == '#') {//如果根结点为空则创建结束
T = NULL;
return 1;
}
BiTree temp=new BiTNode;
BiTree temp1 = new BiTNode;
BiTree newnode = new BiTNode;
if (!newnode || !temp || !temp1)return 0;
LinkStack S;
InitStack(S);
T->data = ch;
T->lchild = NULL;
T->rchild = NULL;
Push(S, T);
while (GetTop(S, temp1))
{
cin >> ch;
GetTop(S, temp);
if (ch != '#' && flag==0)
{
newnode = new BiTNode;
newnode->data = ch;
GetTop(S, temp);
temp->lchild = newnode;
Push(S, newnode);
}
else if (ch != '#' && flag==1)
{
newnode = new BiTNode;
newnode->data = ch;
GetTop(S, temp);
temp->rchild = newnode;
Push(S, newnode);
flag = 0;
}
else if (ch == '#' && flag==0)
{
GetTop(S, temp);
temp->lchild =NULL;
flag = 1;
}
else if (ch == '#' && flag==1)
{
Pop(S, temp);
temp->rchild =NULL;
while (1)
{
GetTop(S, temp1);
if (temp1->rchild==temp)
{
Pop(S, temp);
}
else
{
break;
}
}
}
}
}
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;
}
int Preorder(BiTree T) {
if (T) {
cout << T->data << " ";
Preorder(T->lchild);
Preorder(T->rchild);
return 1;
}
return 0;
}
int Inorder(BiTree T) {
if (T) {
Inorder(T->lchild);
cout << T->data << " ";
Inorder(T->rchild);
return 1;
}
return 0;
}
int Postorder(BiTree T) {
if (T) {
Postorder(T->lchild);
Postorder(T->rchild);
cout << T->data << " ";
return 1;
}
return 0;
}
int InitStack(LinkStack& S) {
S = NULL;
return 1;
}
int Push(LinkStack& S, SElemType e) {
StackNode* temp = new StackNode;
if (!temp)return 0;
temp->data = e;
temp->next = S;
S = temp;
return 1;
}
int Pop(LinkStack& S, SElemType& e) {
if (S == NULL)return 0;
StackNode* temp = S;
e = S->data;
S = S->next;
delete temp;
return 1;
}
int StackEmpty(LinkStack S) {
if (S == NULL)
return 1;
return 0;
}
int GetTop(LinkStack S, SElemType& e) {
if (S == NULL)return 0;
e = S->data;
return 1;
}
花了好久写出来的,可能思路还不是很清晰,欢迎指正。