第6次作业

这个作业属于哪个课程数据结构
这个作业要求在哪里 https://edu.cnblogs.com/campus/qdu/DS2020/homework/11430
这个作业的目标 <1、掌握二叉树的基本特性2、掌握二叉树的先序、中序、后序的递归遍历算法3、理解二叉树的先序、中序、后序的非递归遍历算法4、通过求二叉树的深度、叶子结点数和层序遍历等算法,理解二叉树的基本特性>
学号 2018204106

一、实验目的

1、掌握二叉树的基本特性
2、掌握二叉树的先序、中序、后序的递归遍历算法
3、理解二叉树的先序、中序、后序的非递归遍历算法
4、通过求二叉树的深度、叶子结点数和层序遍历等算法,理解二叉树的基本特性

二、实验预习

说明以下概念
1、二叉树:二叉树是n个有限元素的集合,该集合或者为空、或者由一个称为根的元素及两个不相交的、被分别称为左子树和右子树的二叉树组成,是有序树。当集合为空时,称该二叉树为空二叉树。在二叉树中,一个元素也称作一个结点 。

2、递归遍历:由于二叉树所具有的递归性质,一棵非空的二叉树可以看作是由根节点、左子树和右子树3部分构成,因为若能依次遍历这3部分的信息,也就遍历了整个二叉树。按照左子树的遍历在右子树的遍历之前进行的约定,根访问根节点位置的不同,可以得到二叉的前序、中序、后序3种遍历方法。

3、非递归遍历:不采用递归的方式对二叉树进行遍历,要采用栈去模拟实现。

4、层序遍历:设二叉树的根节点所在层数为1,层序遍历就是从所在二叉树的根节点出发,首先访问第一层的树根节点,然后从左到右访问第2层上的节点,接着是第三层的节点,以此类推,自上而下,自左至右逐层访问树的结点的过程就是层序遍历。

三、实验内容和要求

1、阅读并运行下面程序,根据输入写出运行结果,并画出二叉树的形态。

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<malloc.h>
#define MAX 20
typedef struct BTNode{       /*节点结构声明*/
    char data ;               /*节点数据*/
    struct BTNode *lchild;
    struct BTNode *rchild ;  /*指针*/
}*BiTree;

void createBiTree(BiTree *t){ /* 先序遍历创建二叉树*/
    char s;
    BiTree q;
    printf("\nplease input data:(exit for #)");
    s=getche();
    if(s=='#'){*t=NULL; return;}
    q=(BiTree)malloc(sizeof(struct BTNode));
    if(q==NULL){printf("Memory alloc failure!"); exit(0);}
    q->data=s;
    *t=q;
    createBiTree(&q->lchild); /*递归建立左子树*/
    createBiTree(&q->rchild); /*递归建立右子树*/
}

void PreOrder(BiTree p){  /* 先序遍历二叉树*/
    if ( p!= NULL ) {
           printf("%c", p->data);
           PreOrder( p->lchild ) ;
           PreOrder( p->rchild) ;
    }
}
void InOrder(BiTree p){  /* 中序遍历二叉树*/
    if( p!= NULL ) {
      InOrder( p->lchild ) ;
        printf("%c", p->data);
        InOrder( p->rchild) ;
    }
}
void PostOrder(BiTree p){  /* 后序遍历二叉树*/
   if ( p!= NULL ) {
        PostOrder( p->lchild ) ;
           PostOrder( p->rchild) ;
           printf("%c", p->data);
    }
}

void Preorder_n(BiTree p){ /*先序遍历的非递归算法*/
    BiTree stack[MAX],q;
    int top=0,i;
    for(i=0;i<MAX;i++) stack[i]=NULL;/*初始化栈*/
    q=p;
    while(q!=NULL){
        printf("%c",q->data);
        if(q->rchild!=NULL) stack[top++]=q->rchild;
        if(q->lchild!=NULL) q=q->lchild;
        else
            if(top>0) q=stack[--top];
            else q=NULL;
    }
}

void release(BiTree t){ /*释放二叉树空间*/
      if(t!=NULL){
        release(t->lchild);
        release(t->rchild);
        free(t);
      }
}

int main(){
    BiTree t=NULL;
    createBiTree(&t);
    printf("\n\nPreOrder the tree is:");
    PreOrder(t);
    printf("\n\nInOrder the tree is:");
    InOrder(t);
    printf("\n\nPostOrder the tree is:");
    PostOrder(t);
    printf("\n\n先序遍历序列(非递归):");
    Preorder_n(t);
    release(t);
    return 0;
}

2、在上题中补充求二叉树中求结点总数算法(提示:可在某种遍历过程中统计遍历的结点数),并在主函数中补充相应的调用验证正确性。

算法代码:

 

int PreOrder_num(BiTree p){ 
       int j=0;        
             BiTree stack[MAX],q;
      int top=0,i;
      for(i=0;i<MAX;i++) stack[i]=NULL;
      q=p;
      while(q!=NULL){
            j++;
             if(q->rchild!=NULL) stack[top++]=q->rchild;
             if(q->lchild!=NULL) q=q->lchild;
             else
                     if(top>0) q=stack[--top];
                     else q=NULL;
      }
      return j; 
}

 

3、在上题中补充求二叉树中求叶子结点总数算法(提示:可在某种遍历过程中统计遍历的叶子结点数),并在主函数中补充相应的调用验证正确性。
算法代码:

int LeafNodes(BiTree p){
     int num1,num2;
     if(p==NULL)
         return 0;
     else if(p->lchild==NULL&&p->rchild==NULL)
         return 1;
     else
     {
         num1=LeafNodes(p->lchild);
         num2=LeafNodes(p->rchild);
         return (num1+num2);
      }
}

 

4、在上题中补充求二叉树深度算法,并在主函数中补充相应的调用验证正确性。
算法代码:

int BTNodeDepth(BiTree p){
     int lchilddep,rchilddep;
     if(p==NULL)
         return 0;
     else{
          lchilddep=BTNodeDepth(p->lchild);
          rchilddep=BTNodeDepth(p->rchild);
          return(lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);  
      }
}

 

5、补充二叉树层次遍历算法。(提示:利用队列实现)

void levelOrder(BiTree T){
    if(T==NULL) return;
    InitQueue(Q);//初始化一个队列
    EnQueue(Q,T);
    while(QueueEmpty(s)!=NULL){
        Dequeue(Q,T);
        visit(T);
        if(T->lchild!=NULL) Enqueue(Q,T->lchild);   
        if(T->rchild!=NULL) Enqueue(Q,T->rchild);  
    }
}

 

6、补充二叉树中序、后序非递归算法。

 #include <iostream>
#include<string.h>
#include<stack>
#include<stdlib.h>
using namespace std;

typedef struct node
{
    char data;
    struct node *lchild,*rchild;
}BinTree;

typedef struct node1
{
    BinTree *btnode;
    bool isFirst;
}BTNode;


void creatBinTree(char *s,BinTree *&root)  //创建二叉树,s为形如A(B,C(D,E))形式的字符串
{
    int i;
    bool isRight=false;
    stack<BinTree*> s1;//结点
    stack<char> s2; //分隔符
    BinTree *p,*temp;
    root->data=s[0];
    root->lchild=NULL;
    root->rchild=NULL;
    s1.push(root);
    i=1;
    while(i<strlen(s))
    {
        if(s[i]=='(')
        {
            s2.push(s[i]);
            isRight=false;
        }
        else if(s[i]==',')
        {
            isRight=true;
        }
        else if(s[i]==')')
        {
            s1.pop();
            s2.pop();
        }
        else if(isalpha(s[i]))
        {
            p=(BinTree *)malloc(sizeof(BinTree));
            p->data=s[i];
            p->lchild=NULL;
            p->rchild=NULL;
            temp=s1.top();
            if(isRight==true)
            {
                temp->rchild=p;
                cout<<temp->data<<"右孩子是"<<s[i]<<endl;
            }
            else
            {
                temp->lchild=p;
                cout<<temp->data<<"左孩子是"<<s[i]<<endl;
            }
            if(s[i+1]=='(')
                s1.push(p);
        }
        i++;
    }
}

void display(BinTree *root)        //显示树形结构
{
    if(root!=NULL)
    {
        cout<<root->data;
        if(root->lchild!=NULL)
        {
            cout<<'(';
            display(root->lchild);
        }
        if(root->rchild!=NULL)
        {
            cout<<',';
            display(root->rchild);
            cout<<')';
        }
    }
}

void preOrder1(BinTree *root)     //递归前序遍历
{
    if(root!=NULL)
    {
        cout<<root->data<<" ";
        preOrder1(root->lchild);
        preOrder1(root->rchild);
    }
}

void inOrder1(BinTree *root)      //递归中序遍历
{
    if(root!=NULL)
    {
        inOrder1(root->lchild);
        cout<<root->data<<" ";
        inOrder1(root->rchild);
    }
}

void postOrder1(BinTree *root)    //递归后序遍历
{
    if(root!=NULL)
    {
        postOrder1(root->lchild);
        postOrder1(root->rchild);
        cout<<root->data<<" ";
    }
}

void preOrder2(BinTree *root)     //非递归前序遍历
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {
            cout<<p->data<<" ";
            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            s.pop();
            p=p->rchild;
        }
    }
}

void inOrder2(BinTree *root)      //非递归中序遍历
{
    stack<BinTree*> s;
    BinTree *p=root;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)
        {
            s.push(p);
            p=p->lchild;
        }
        if(!s.empty())
        {
            p=s.top();
            cout<<p->data<<" ";
            s.pop();
            p=p->rchild;
        }
    }
}

void postOrder2(BinTree *root)    //非递归后序遍历
{
    stack<BTNode*> s;
    BinTree *p=root;
    BTNode *temp;
    while(p!=NULL||!s.empty())
    {
        while(p!=NULL)              //沿左子树一直往下搜索,直至出现没有左子树的结点
         {
            BTNode *btn=(BTNode *)malloc(sizeof(BTNode));
            btn->btnode=p;
            btn->isFirst=true;
            s.push(btn);
            p=p->lchild;
        }
        if(!s.empty())
        {
            temp=s.top();
            s.pop();
            if(temp->isFirst==true)     //首次出现在栈顶
             {
                temp->isFirst=false;
                s.push(temp);
                p=temp->btnode->rchild;
            }
            else                        //第二次出现在栈顶
             {
                cout<<temp->btnode->data<<" ";
                p=NULL;
            }
        }
    }
}

void postOrder3(BinTree *root)     //非递归后序遍历
{
    stack<BinTree*> s;
    BinTree *cur;                      //当前结点
    BinTree *pre=NULL;                 //前一次访问的结点
    s.push(root);
    while(!s.empty())
    {
        cur=s.top();
        if((cur->lchild==NULL&&cur->rchild==NULL)||
           (pre!=NULL&&(pre==cur->lchild||pre==cur->rchild)))
        {
            cout<<cur->data<<" ";  
              s.pop();
            pre=cur;
        }
        else
        {
            if(cur->rchild!=NULL)
                s.push(cur->rchild);
            if(cur->lchild!=NULL)
                s.push(cur->lchild);
        }
    }
}


int main(int argc, char *argv[])
{
    char s[100];
    while(scanf("%s",s)==1)
    {
        BinTree *root=(BinTree *)malloc(sizeof(BinTree));
        creatBinTree(s,root);
        display(root);
        cout<<endl;
        preOrder2(root);
        cout<<endl;
        inOrder2(root);
        cout<<endl;
        postOrder2(root);
        cout<<endl;
        postOrder3(root);
        cout<<endl;
    }
    return 0;
}
posted @ 2020-11-07 16:38  年迈剑圣  阅读(357)  评论(0编辑  收藏  举报