算法学习19-实现二叉树的先序、中序、后序遍历,包括递归方式和非递归方式及深搜和宽搜

算法学习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");
}
发布了27 篇原创文章 · 获赞 1 · 访问量 1027

猜你喜欢

转载自blog.csdn.net/qq_45205390/article/details/104200920