第六次作业

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

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

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

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

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

三、实验内容和要求
1、阅读并运行下面程序,根据输入写出运行结果,并画出二叉树的形态。

#include<stdio.h>
#include<malloc.h>
#include<iostream>
#include<conio.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;
}

输入:
ABC##DE#G##F###
运行结果:

二叉树形态:

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、补充二叉树中序、后序非递归算法。
中序:

void NRPreOrder(BiTree t)   //非递归先序遍历二叉树
{    
    BiTree stack[maxsize],p;
    int top;                //栈顶
    if(bt==NULL) return;    //树为空则返回
    top=0;
    p=bt;                   
    while(!(p==NULL&&top==0))       //当根结点不为空且栈不为空时
        {
            while(p!=NULL)          //先深入左子树
            {
                   if(top<=maxsize-1)  
                    {
                    stack[top]=p;          //入栈
                       top++;              //栈顶位置++
                    }
                    else                   //栈满时
                    {
                    printf("栈溢出");
                    return;
                    }
                p=p->lchild;            //深入当前根结点的左子树
            }
            if(top<=0)return;
            else
                    {
                    top--;             //栈顶--,
                    p=stack[top];      //弹出栈顶元素
                    printf("%2c",&p->data);   //在此处用打印表示访问该结点
                    p=p->rchild;       //指向右子树
                    }
}

后序:

void Nrpostorder(BiTree T)
{
    stacktype stack[max];
    BiTree p;
    int top,sign;
    if(T==NULL) return;
    top=-1;
    p=T;
    while(!(p==NULL&&top==-1))
        {
            if(p!=NULL)
            {
                top++;
                stack[top].link=p;
                stack[top].flag=1;
                p=p->lchild;
            }
            else
            {
                p=stack[top].link;
                sign=stack[top].flag;
                top--;
                if(sign==1)
                    {
                        top++;
                        stack[top].link=p;
                        stack[top].flag=2;
                        p=p->rchild;
                    }
                else
                    {
                        printf("%2c",p->data);
                        p=NULL;
                    }
            }
        }
} 

四、实验小结
通过实验,了解了二叉树的基本特性,学习了二叉树的先序、中序、后序的递归遍历算法和非递归遍历算法,还学习了求二叉树的深度、叶子结点数和层序遍历等算法,更加深刻的理解了二叉树的基本特性。

posted @ 2020-11-06 23:10  李小锟  阅读(198)  评论(0)    收藏  举报