代码
#include<stdio.h>
#include<iostream>
#include <stack>
using namespace std;
typedef char ElemType; //ElemType 为可定义的数据类型,此设为int类型
typedef struct BiTNode {
ElemType data; //结点的数据域
struct BiTNode *lchild, *rchild; //左右孩子
}BiTNode, *BiTree;
/*先序遍历的顺序建立二叉链表*/
/**
假设二叉树中结点的元素均为一个单字符。假设按照现需遍历的顺序建立二叉树链表,
T为指向根节点的指针:说先输入一个根节点,若输入的是一个“#”字符,则表明该
二叉树为空数,即T为NULL;否则输入的该字符赋给T->data,之后一次递归建立它的左
子数T->lchild和右子树T->rchild。
**/
void createBiTree(BiTree &T) {
char ch;
cin>>ch;
if(ch=='#') T=NULL; //递归结束,建立空数
else{
T = new BiTNode; //生成根节点
T->data = ch;
createBiTree(T->lchild); //递归创建左子树
createBiTree(T->rchild); //递归创建右子数
}
}
/*前序遍历二叉树T的递归算法*/
// 若二叉树为空,则空操作
// (1)访问根节点
// (2)前序遍历左子树
// (3)前序遍历右子树
void preOrderTraverse(BiTree T) {
if(T){
cout<<T->data;
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
/*中序遍历二叉树T的递归算法*/
// 若二叉树为空,则空操作;否则
// (1)中序遍历左子树;
// (2)访问根节点;
// (3)中序遍历右子数。
void inOrderTraverse(BiTree T){
if(T){
inOrderTraverse(T->lchild);
cout<<T->data;
inOrderTraverse(T->rchild);
}
}
/*后序遍历二叉树T的递归算法*/
// 若二叉树为空,则空操作
// (1)后序遍历左子树
// (2)后序遍历右子数
// (3)访问根节点。
void postOrderTraverse(BiTree T){
if(T){
postOrderTraverse(T->lchild);
postOrderTraverse(T->rchild);
cout<<T->data;
}
}
/*前序遍历遍历二叉树非递归算法*/
// 假设p为指向根节点的指针
// (1)当p非空时,访问p并将p所指的结点的地址进栈,p指向该节点的左孩子
// (2)当p为空时,弹出栈顶元素,将p指向该结点的右孩子;
// (3)重复以上两步骤,直到栈空且p也为空。
void preOrderTraverse_(BiTree T) {
std::stack<BiTNode*> stacktree;
BiTNode* p = T;
while(p||!stacktree.empty()){
if(p) {
cout<<p->data;
stacktree.push(p);
p = p->lchild;
} else {
p = stacktree.top();
stacktree.pop();
p=p->rchild;
}
}
}
/*中序遍历遍历二叉树非递归算法*/
// 假设p为指向根节点的指针
// (1)当p非空时,将p所指的结点的地址进栈,p指向该节点的左孩子
// (2)当p为空时,弹出栈顶元素并访问,将p指向该结点的右孩子;
// (3)重复以上两步骤,直到栈空且p也为空。
void inOrderTraverse_(BiTree T) {
std::stack<BiTNode*> stacktree;
BiTNode* p = T;
while(p||!stacktree.empty()){
if(p) { //p非空根指针进栈,遍历左子树
stacktree.push(p);
p = p->lchild;
} else { //p为空根指针退栈,访问根节点,遍历右子数
p = stacktree.top();
cout<<p->data;
stacktree.pop();
p=p->rchild;
}
}
}
/*后序遍历遍历二叉树非递归算法*/
// 假设p为指向根节点的指针
// (1)现将p结点入栈
// (2)若P不存在左孩子和右孩子,或者P存在左孩子或右孩子,但左右孩子已经被输出,则可以直接输出节点P,并将其出栈,
// 将出栈节点P标记为上一个输出的节点,再将此时的栈顶结点设为当前节点;
// (3)若不满足(2)中的条件,则将P的右孩子和左孩子依次入栈,当前节点重新置为栈顶结点,之后重复操作(2)。
// (4)直到栈空,遍历结束。
void postOrderTraverse_(BiTree T) {
std::stack<BiTNode*> stacktree;
BiTNode* p = T;
BiTNode* pPre = NULL;
stacktree.push(T);
while(!stacktree.empty()){
p = stacktree.top();
if((p->lchild==NULL && p->rchild==NULL)||(p!=NULL && (p->lchild==pPre || p->rchild==pPre))){
cout<<p->data;
stacktree.pop();
pPre = p;
} else {
if(p->rchild != NULL) {
stacktree.push(p->rchild);
}
if(p->lchild != NULL) {
stacktree.push(p->lchild);
}
}
}
}
/**
创建这个二叉树进行测试
(-)
/ \
(+) (/)
/ \ / \
(a) (*) (e) (f)
/ \
(b) (-)
/ \
(c) (b)
**/
void main() {
BiTree tree;
cout<<"请输入二叉链表序列:\n";
createBiTree(tree);
cout<<"\n\n";
cout<<"非递归先序输出:\n";
preOrderTraverse_(tree);
cout<<"\n";
cout<<"递归先序输出:\n";
preOrderTraverse(tree);
cout<<"\n\n";
cout<<"非递归中序输出\n";
inOrderTraverse_(tree);
cout<<"\n";
cout<<"递归中序输出\n";
inOrderTraverse(tree);
cout<<"\n\n";
cout<<"非递归后序输出\n";
postOrderTraverse_(tree);
cout<<"\n";
cout<<"递归后序输出\n";
postOrderTraverse(tree);
cout<<"\n\n";
}