直接看代码吧,理论知识略了,网上一搜一大把,本篇主要记录代码实现过程。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<stack>
#include<queue>
using namespace std;
/*二叉树链式存储结构*/
typedef struct BiTNode{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
/*先序创建二叉树*/
int CreateBiTree(BiTree &T){
char data;
scanf("%c",&data);
if(data=='#'){ //'#'号表示空树
T=NULL;
}
else{
T=(BiTree)malloc(sizeof(BiTNode)); //T=(BiTNode*)malloc(sizeof(BiTNode)); 也可以
T->data=data;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
return 0;
}
/*访问节点*/
void Visit(BiTree T){
if(T) printf("%c ",T->data);
}
/*递归先序遍历*/
void PreOrder(BiTree T){
if(T!=NULL){
Visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
/*递归中序遍历*/
void InOrder(BiTree T){
if(T!=NULL){
InOrder(T->lchild);
Visit(T);
InOrder(T->rchild);
}
}
/*递归后序遍历*/
void PostOrder(BiTree T){
if(T!=NULL){
PostOrder(T->lchild);
PostOrder(T->rchild);
Visit(T);
}
}
/*非递归先序遍历*/
void PreOrder2(BiTree T){
stack<BiTree> s; //申请树节点指针类型栈
BiTree p = T; //p是遍历指针
while(p || !s.empty()){ //p不空或栈不空时循环
if(p != NULL){
Visit(p); //访问节点
s.push(p); //根指针进栈
p = p->lchild; //遍历左子树
}
else{ //根指针退栈,遍历右子树
p = s.top();
s.pop();
p = p->rchild;
}
}
}
/*非递归中序遍历*/
void InOrder2(BiTree T){
stack<BiTree> s;
BiTree p = T;
while(p || !s.empty()){
if(p != NULL){
s.push(p);
p = p->lchild;
}
else{
p = s.top();
s.pop();
Visit(p);
p = p->rchild;
}
}
}
/*非递归后续遍历*/
void PostOrder2(BiTree T){
stack<BiTree> s;
BiTree p = T, r = NULL;
while(p || !s.empty()){
if(p != NULL){ //一直往左走
s.push(p);
p = p->lchild;
}
else{ //向右
p = s.top(); //取栈顶节点
if(p->rchild && p->rchild!=r){ //如果右子树存在,且未被访问过
p = p->rchild; //转向右
s.push(p);
p = p->lchild; //再往左走
}
else{ //否则,弹出节点并访问
s.pop();
Visit(p);
r = p; //记录最近访问过的节点
p = NULL; //节点访问完后,重置p指针
}
}
}
}
/*非递归层次遍历*/
void LevelOrder(BiTree T){
queue<BiTree> Q;
BiTree p = T; //遍历指针
Q.push(p); //根结点入队
while(!Q.empty()){ //队列非空则循环
p = Q.front(); //取队头元素
Q.pop();
Visit(p);
if(p->lchild != NULL) //左子树非空,则左子树入队列
Q.push(p->lchild);
if(p->rchild != NULL) //右子树非空,则右子树入队列
Q.push(p->rchild);
}
}
int main(){
BiTree T;
CreateBiTree(T);
printf("————————————————————\n");
printf("递归先序遍历:");
PreOrder(T);
printf("\n递归中序遍历:");
InOrder(T);
printf("\n递归后序遍历:");
PostOrder(T);
printf("\n————————————————————");
printf("\n非递归先序遍历:");
PreOrder2(T);
printf("\n非递归中序遍历:");
InOrder2(T);
printf("\n非递归后序遍历:");
PostOrder2(T);
printf("\n————————————————————");
printf("\n非递归层次遍历:");
LevelOrder(T);
return 0;
}
程序测试:
输入:ABD#G###CEH###F##
参考文章:
1、点此链接 (这篇文章写的很用心,博主把栈和队列的相关操作都自己写出来了,值得学习)
2、点此链接 (他用了两种方法,第二种方法中结构体的申明、初始化,容器的使用)
3、点此链接 (二叉树相关的操作实现)