二叉树的遍历(包括层次遍历)——数据结构课设

文章中部分参考了百度以及CSDN上大佬的代码,例如层次遍历那部。代码中的注释是自己编写,可以更好理解。二叉树的遍历还有一种可以不用递归的方法,此处并没写。仅供参考。

#include<iostream>
#include<string.h>
using namespace std;
#define MAX 100
typedef struct bitree
{
    char data;
    struct bitree *lchild;
    struct bitree *rchild;
}Binode,*Bitree;//结构体 Bitree是指针类型 
void createBiTree(Bitree &bt)//建立二叉树 
{
    char ch;//定义一个字符变量 
    cin>>ch;//输入字符 
    if(ch=='#')//#是此节点为空的条件 
    {
    bt=NULL;// 树为空 
    return;//直接带回 
    }
    bt=new Binode;//申请一个新节点 
    bt->data=ch;//将输入的字符赋值给根节点 
    createBiTree(bt->lchild);//采用递归建立树的左子树和右子树 
    createBiTree(bt->rchild);
   
}
void preOrder(Bitree bt)//先序遍历 
{
    if(bt){//树不为空 
        cout<<bt->data<<" ";//先输出根节点 
        preOrder(bt->lchild);//采用递归先序遍历左子树和右子树  
        preOrder(bt->rchild);
    }
}

void inOrder(Bitree bt)//中序遍历 
{
    if(bt){
        inOrder(bt->lchild);
        cout<<bt->data<<" ";//中间输出根节点 
        inOrder(bt->rchild);
    }
}
void postOrder(Bitree bt)//后续遍历 
{
    if(bt){
        postOrder(bt->lchild);
        postOrder(bt->rchild);
        cout<<bt->data<<" ";//最后输出根节点 
    }
}
void levelOrder(Bitree bt)//层序遍历,采用队实现
{
    Bitree Queue[MAX],b;// 创建一个结构体类型的数组(作为队列)和 b对象; 
    int front,rear;//定义队尾队首下标 
    front=rear=0;//初始化队尾和队首为0 
    if(bt)//树不为空 
    {
        Queue[rear++]=bt;//将根节点入队 
    while(front!=rear)//队不为空 
    {
        b=Queue[front++]; //将队首元素(即根节点)赋给b; 
        cout<<b->data<<" ";//输出b的数据域 
        if(b->lchild!=NULL)//左子树不为空 
            Queue[rear++]=b->lchild;//左子树进队 
        if(b->rchild!=NULL)//右子树不为空 
            Queue[rear++]=b->rchild;//将右子树入队 
    }   
  }
}
void FpreOrder(Bitree bt)//非递归先序遍历算法
{
    Bitree Stack[MAX],p;//结构体类型的栈Stack 
    int top = -1;// 栈顶下标 
    Stack[++top] = bt;//将根节点入栈 
    while(top!= -1)//栈不为空 
    {
        p = Stack[top--];//栈顶元素即根节点赋值给p 
        cout << p->data << " ";
        if(p->rchild)
        Stack[++top] = p->rchild;//右子树入栈 
        if(p->lchild)
        Stack[++top] = p->lchild;//左子树入栈 
    }
}
void FinOrder(Bitree bt)//迭代中序遍历2
{
    if(bt != NULL)//树不为空 
    {
        Bitree Stack[MAX],p;//定义一个结构体类型的栈和p指针 
        int top = -1;//栈顶下标初始化-1 
        p =bt;//把二叉树赋给p 
        while (top != -1 || p != NULL)//栈不为空且p不为空 
        {
            if (p != NULL)//p不为空 
            {
                Stack[++top] = p;//p入栈  
                p = p->lchild;//p指向左子树 
            }//左子树入栈 
            else//栈不为空 
            {
                p = Stack[top--];//p等于栈顶元素 最左的节点弹出
                cout << p->data <<' ';//输出根节点 
                p = p->rchild;//p指向右子树,接下来右子树入栈 ,遍历右子树
            }
        }
    }
}
int FpostOrder(Bitree bt)
{
    Bitree p = bt, Stack[MAX], pre;//
    int top = 0, flag = 1;
    if(p)
    do{
     while(p)
     {
         Stack[top++] = p;
          p = p->lchild;
  } // p所有左节点入栈
        flag = 1;
       while(top != 0 && flag == 1)
       {
          p = Stack[top-1];//取栈顶元素但不输出
         if(p->rchild == pre || p->rchild == NULL)
         {
         //右孩子不存在或右孩子已访问
         top--;
          cout<< p->data<<' ';
          pre = p; //指向被访问节点
          }
        else {
                    //继续遍历右子树
                    p = p->rchild;
                    flag = 0;//
                }
        }
          }while(top != 0);
    return 1;
}//
void print(Bitree bt)
{
    int n;
    cout<<"选择你想采用的遍历的方法;1先序,2中序,3后序,4层序,5非递归先序,6非递归中序,7非递归后序,0结束:" <<endl;
    cin>>n;
    while(n)
    {
        
       if(n==1)
    {
        cout<<"输出先序遍历的结果:";
        preOrder(bt);
    }
    if(n==2)
    {
       cout<<"输出中序遍历的结果:";
       inOrder(bt);
       
    }
    if(n==3)
    {
        cout<<"输出后序遍历的结果:";
        postOrder(bt);
    }
    if(n==4)
    {
      cout<<"输出层次遍历的结果:";
       levelOrder(bt);
    } 
    if(n==5)
    {
      cout<<"输出非递归先序遍历的结果:";
       FpreOrder(bt);
    } 
    if(n==6)
    {
      cout<<"输出非递归中序遍历的结果:";
       FinOrder(bt);
    } 
    if(n==7)
    {
      cout<<"输出非递归后序遍历的结果:";
       FpostOrder(bt);
    } 
    /*if(n!=1&&n!=2&&n!=3&&n!=4&&n!=5&&n!=6&&n!=7)
     cout<<"输入错误,请重新选择:";*/
     while(n>7)
     {
     cout<<"输入错误,请重新选择!"<<endl;
     break;
     }
    cout<<endl;
    //cout<<"选择你想采用的遍历的方法:1 先序,2 中序,3 后序,4 层序,0 结束:" <<endl;
    cin>>n;
   }
}
//水平画树,画分支 
void draw_level(Bitree bt,bool left,char* str) //bool 在c++中是一个数据类型只有两个选择 返回值只有真true或假flase 
{//在此处left是判断左右 
    if (bt->rchild) {//右子树不为空 (判断左右子树顺序不能调换) 
        draw_level(bt->rchild,false,strcat(str,(left ? "|     " : "      ")));//strcat是用来拼接字符串 
    }//递归 画右子树 

    cout<<str;
    cout<<(left ? '\\': '/');//条件运算符  真(左)则输出'\\'假 (右 )则输出'/' 
    //反斜杠是转义字符的开头,要使用\\表示,也即'\\'
    cout<<"-----";
    cout<<bt->data;
    cout<<endl;

    if (bt->lchild) {
        draw_level(bt->lchild, true, strcat(str, (left ? "      " : "|     ")));
    }
    str[strlen(str)-6]='\0';//字符串结束 
}
void draw(Bitree root) {//根节点画树 
    char str[MAX];
    memset(str, '\0', MAX);//初始化字符串,都赋值为'\0' 
    if (root->rchild) {
        draw_level(root->rchild, false, str);
    }//画右子树 
    cout<<root->data;//输出根节点 
    cout<<endl;
    if (root->lchild) {
        draw_level(root->lchild, true, str);
    }//画左子树 
}
int main()
{
    Binode *bt;//创建一个结构体类型的变量bt
    char *str;//定义一个字符指针类型的字符串 
    cout<<endl; 
    cout<<"      请输入你想添加的节点,输入'#'则此节点为NULL:"<<endl;
    createBiTree(bt);//调用创建二叉树的函数 
    cout<<"二叉树建立成功!"<<endl;
    cout<<endl;
    cout<<"画出二叉树为:"<<endl;
    draw(bt);
    print(bt);
    return 0; 
}
 

猜你喜欢

转载自blog.csdn.net/qq_52383168/article/details/121918983
今日推荐