算法学习19-实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式及深搜和宽搜
文章目录
实现二叉树的先序、中序、后序遍历
相关知识
二叉树的遍历主要有三种:
(1)先(根)序遍历(根左右)
(2)中(根)序遍历(左根右)
(3)后(根)序遍历(左右根)
(4)先(根)序遍历(逐层输出)
举个例子:
先(根)序遍历(根左右):A B D H E I C F J K G
中(根)序遍历(左根右) : D H B E I A J F K C G
后(根)序遍历(左右根) : H D I E B J K F G C A
递归行为
#include<iostream>
using namespace std;
struct node {
int Number;
struct node* Left;
struct node* Right;
};
//输出信息
void PrintList(int Number)
{
printf("%d ", Number);
}
//前遍历
void PreOrder(struct node* root)
{
if (root == NULL)
return;
PrintList(root->Number);
PreOrder(root->Left);
PreOrder(root->Right);
}
//中遍历
void InOrder(struct node* root)
{
if (root == NULL)
return;
InOrder(root->Left);
PrintList(root->Number);
InOrder(root->Right);
}
//后遍历
void PostOrder(struct node* root)
{
if (root == NULL)
return;
PostOrder(root->Left);
PostOrder(root->Right);
PrintList(root->Number);
}
//
int GetMaxWidth(struct node*pointer){
int width[10];//加入这棵树的最大高度不超过10
int maxWidth=0;
int floor=1;
if(pointer){
width[floor]++;
floor++;
if (pointer->Left)
width[floor]++;
if (pointer->Right)
width[floor]++;
if(maxWidth<width[floor])
maxWidth=width[floor];
GetMaxWidth(pointer->Left);
floor--;//记得退回一层,否则会出错。因为已经Get过了,所以要及时的返回。
GetMaxWidth(pointer->Right);
}
return maxWidth;
}
非递归行为
#include <malloc.h>
#include <stack>
#include <iostream>
using namespace std;
typedef struct BiTNode{
char data;
BiTNode *lchild, *rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)//建树,按先序顺序输入节点
{
char ch;
scanf("%c",&ch);
if(ch==' ')
{
T=NULL;
return;
}
else
{
T=(BiTree)malloc(sizeof(BiTNode));
if(!T)
exit(1);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void InOrderTraverse(BiTree T)//非递归中序遍历
{
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
T=T->lchild;
}
T=Stack.top();
Stack.pop();
printf("%c",T->data);
T=T->rchild;
}
}
void PreOrderTraverse(BiTree T)//非递归先序遍历
{
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
printf("%c",T->data);
T=T->lchild;
}
T=Stack.top();
Stack.pop();
T=T->rchild;
}
}
void PostOrderTraverse(BiTree T)//非递归后序遍历,用一个标记标记右子树是否访问过
{
int flag[20];
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T)
{
Stack.push(T);
flag[Stack.size()]=0;
T=T->lchild;
}
while(!Stack.empty())
{
T=Stack.top();
while(T->rchild && flag[Stack.size()]==0)
{
flag[Stack.size()]=1;
T=T->rchild;
while(T)
{
Stack.push(T);
flag[Stack.size()]=0;
T=T->lchild;
}
}
T=Stack.top();
printf("%c",T->data);
Stack.pop();
}
}
int main()
{
BiTree T;
CreateBiTree(T);
PreOrderTraverse(T);
printf("\n");
InOrderTraverse(T);
printf("\n");
PostOrderTraverse(T);
printf("\n");
}
实现树的深度
#include<iostream>
using namespace std;
struct node {
int Number;
struct node* Left;
struct node* Right;
};
int maxHeight(node *root) {
if(root==NULL){
return 0;
}
int nLeft=maxHeight(root->Left);
int nRight=maxHeight(root->Right);
return nLeft>nRight?nLeft+1:nRight+1;
}
实现树的宽度
int GetMaxWidth(struct node*pointer){
int width[10];//加入这棵树的最大高度不超过10
int maxWidth=0;
int floor=1;
if(pointer){
width[floor]++;
floor++;
if (pointer->Left)
width[floor]++;
if (pointer->Right)
width[floor]++;
if(maxWidth<width[floor])
maxWidth=width[floor];
GetMaxWidth(pointer->Left);
floor--;//记得退回一层,否则会出错。因为已经Get过了,所以要及时的返回。
GetMaxWidth(pointer->Right);
}
return maxWidth;
}
总结
文章到最后,我们来看两个源文件
实现二叉树的先序、中序、后序遍历,包括递归方式
#include<iostream>
using namespace std;
struct node {
int Number;
struct node* Left;
struct node* Right;
};
int maxHeight(node *root) {
if(root==NULL){
return 0;
}
int nLeft=maxHeight(root->Left);
int nRight=maxHeight(root->Right);
return nLeft>nRight?nLeft+1:nRight+1;
}
void PrintList(int Number)
{
printf("%d ", Number);
}
void PreOrder(struct node* root)
{
if (root == NULL)
return;
PrintList(root->Number);
PreOrder(root->Left);
PreOrder(root->Right);
}
void InOrder(struct node* root)
{
if (root == NULL)
return;
InOrder(root->Left);
PrintList(root->Number);
InOrder(root->Right);
}
void PostOrder(struct node* root)
{
if (root == NULL)
return;
PostOrder(root->Left);
PostOrder(root->Right);
PrintList(root->Number);
}
void PrintHeight(struct node *p, int Height)
{
if (!p) return;
if (Height == 1) {
PrintList(p->Number);
} else {
PrintHeight(p->Left, Height-1);
PrintHeight(p->Right, Height-1);
}
}
void PrintHeightOrder(struct node *root)
{
int height = maxHeight(root); //maxHeight计算二叉树高度,如二叉树实例高度为3
for (int Height = 1; Height <= height; Height++) {
PrintHeight(root,Height);
printf("\n");
}
}
int GetMaxWidth(struct node*pointer){
int width[10];//加入这棵树的最大高度不超过10
int maxWidth=0;
int floor=1;
if(pointer){
width[floor]++;
floor++;
if (pointer->Left)
width[floor]++;
if (pointer->Right)
width[floor]++;
if(maxWidth<width[floor])
maxWidth=width[floor];
GetMaxWidth(pointer->Left);
floor--;//记得退回一层,否则会出错。因为已经Get过了,所以要及时的返回。
GetMaxWidth(pointer->Right);
}
return maxWidth;
}
实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式
#include <malloc.h>
#include <stack>
#include <iostream>
using namespace std;
typedef struct BiTNode{
char data;
BiTNode *lchild, *rchild;
}BiTNode,*BiTree;
void CreateBiTree(BiTree &T)//建树,按先序顺序输入节点
{
char ch;
scanf("%c",&ch);
if(ch==' ')
{
T=NULL;
return;
}
else
{
T=(BiTree)malloc(sizeof(BiTNode));
if(!T)
exit(1);
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void InOrderTraverse(BiTree T)//非递归中序遍历
{
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
T=T->lchild;
}
T=Stack.top();
Stack.pop();
printf("%c",T->data);
T=T->rchild;
}
}
void PreOrderTraverse(BiTree T)//非递归先序遍历
{
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T || !Stack.empty())
{
while(T)
{
Stack.push(T);
printf("%c",T->data);
T=T->lchild;
}
T=Stack.top();
Stack.pop();
T=T->rchild;
}
}
void PostOrderTraverse(BiTree T)//非递归后序遍历,用一个标记标记右子树是否访问过
{
int flag[20];
stack<BiTree> Stack;
if(!T)
{
printf("空树!\n");
return;
}
while(T)
{
Stack.push(T);
flag[Stack.size()]=0;
T=T->lchild;
}
while(!Stack.empty())
{
T=Stack.top();
while(T->rchild && flag[Stack.size()]==0)
{
flag[Stack.size()]=1;
T=T->rchild;
while(T)
{
Stack.push(T);
flag[Stack.size()]=0;
T=T->lchild;
}
}
T=Stack.top();
printf("%c",T->data);
Stack.pop();
}
}
int main()
{
BiTree T;
CreateBiTree(T);
PreOrderTraverse(T);
printf("\n");
InOrderTraverse(T);
printf("\n");
PostOrderTraverse(T);
printf("\n");
}