C++——二叉树的递归于非递归遍历

#include <iostream>
#include <cstdio>
#include <stdlib.h>
using namespace std;


typedef struct tree
{
char data;
struct tree *lchild;
struct tree *rchild;
}*Ptree;


typedef Ptree ElementType;




typedef struct SNode *Stack;
struct SNode
{
ElementType Data;
struct SNode *Next;
};




Stack CreateStack();
//判断是否空
int IsEmpty(Stack S);
//Push操作
void Push(ElementType item, Stack S);
//Pop操作
ElementType Pop(Stack S);


//树的建立
Ptree createTree();
//先序遍历
void preOrder(Ptree t);
//中序遍历
void intOrder(Ptree t);
//后序遍历
void postOrder(Ptree t);


//利用栈先序遍历二叉树
void PreOderTraversal(Ptree BT);
//利用栈中序遍历二叉树
void InOderTraversal(Ptree BT);
//利用栈后序遍历
void PostOderTraversal(Ptree BT);
//利用双栈法后序遍历
void PostOderTraversal2(Ptree BT);






int main()
{
Ptree t;
printf("先序创建二叉树,用空格代表虚结点:\n");
t = createTree();
printf("前序遍历:");
preOrder(t);
printf("\n");
printf("利用堆栈前序遍历:");
PreOderTraversal(t);
printf("\n");
printf("\n");


printf("中序遍历:");
intOrder(t);
printf("\n");
printf("利用堆栈中序遍历:");
InOderTraversal(t);
printf("\n");
printf("\n");


printf("后序遍历:");
postOrder(t);
printf("\n");
printf("利用堆栈后序遍历:");
PostOderTraversal(t);
printf("\n");
printf("利用双栈法后序遍历:");
PostOderTraversal2(t);


system("pause");
return 0;
}






//堆栈的建立
Stack CreateStack()
{
Stack S;
S = (Stack)malloc(sizeof(struct SNode));
S->Next = NULL;
return S;
}
//判断是否空
int IsEmpty(Stack S)
{
return(S->Next == NULL);
}
//Push操作
void Push(ElementType item, Stack S)
{
struct SNode *TmpCell;
TmpCell = (struct SNode *)malloc(sizeof(struct SNode));
TmpCell->Data = item;
TmpCell->Next = S->Next;
S->Next = TmpCell;
}


//Pop操作
ElementType Pop(Stack S)
{
struct SNode *FirstCell;
ElementType TopElem;
if (IsEmpty(S))
{
printf("堆栈空\n");
return NULL;
}
else
{
FirstCell = S->Next;
S->Next = FirstCell->Next;
TopElem = FirstCell->Data;
free(FirstCell);
return TopElem;
}
}


Ptree createTree()   //树的建立
{
char ch;
Ptree t;
ch = getchar();  //输入二叉树数据
if (ch == ' ')  //判断二叉树是否为空
t = NULL;
else
{
t = (Ptree)malloc(sizeof(Ptree));  //二叉树的生成
t->data = ch;
t->lchild = createTree();
t->rchild = createTree();
}
return t;
}


void preOrder(Ptree t)  //先序遍历
{
if (t)
{
printf("%c", t->data);
preOrder(t->lchild);
preOrder(t->rchild);
}
}


void intOrder(Ptree t)  //中序遍历
{
if (t)
{
intOrder(t->lchild);
printf("%c", t->data);
intOrder(t->rchild);
}
}


void postOrder(Ptree t)  //后序遍历
{
if (t)
{
postOrder(t->lchild);
postOrder(t->rchild);
printf("%c", t->data);
}
}


//利用栈先序遍历
void PreOderTraversal(Ptree BT)
{
Ptree T = BT;
Stack S = CreateStack();
while (T || !IsEmpty(S))
{
while (T)
{
printf("%c", T->data);
Push(T, S);
T = T->lchild;
}
T = Pop(S);
T = T->rchild;
}
};


//利用栈中序遍历
void InOderTraversal(Ptree BT)
{
Ptree T = BT;
Stack S = CreateStack();
while (T || !IsEmpty(S))
{
while (T)
{
Push(T, S);
T = T->lchild;
}
T = Pop(S);
printf("%c", T->data);
T = T->rchild;
}
};


//利用栈后序遍历
void PostOderTraversal(Ptree BT)
{
Ptree T = BT;
Ptree TempT = NULL;//Temp记录被检查的节点的右儿子
Stack S = CreateStack();
while (T || !IsEmpty(S))
{
while (T)
{
Push(T, S);
T = T->lchild;
}
T = Pop(S);
Push(T, S);//相当于返回了栈顶元素
   // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点
if (T->rchild == NULL || T->rchild == TempT)
{
printf("%c", T->data);
TempT = T;
Pop(S);
T = NULL;
}
// 否则访问右孩子
else
T = T->rchild;
}
};




//利用双栈法后序遍历
void PostOderTraversal2(Ptree BT) // 后序遍历的非递归     双栈法
{
Ptree T = BT; // 指向当前要检查的节点
Stack S1 = CreateStack();
Stack S2 = CreateStack();
Push(T, S1);
while (!IsEmpty(S1))  // 栈空时结束
{
T = Pop(S1);
Push(T, S2);
if (T->lchild)
Push(T->lchild, S1);
if (T->rchild)
Push(T->rchild, S1);
}
while (!IsEmpty(S2))
{
printf("%c", Pop(S2)->data);
}
}

猜你喜欢

转载自blog.csdn.net/qq_40794602/article/details/80255665