数据结构与算法-实验2 树的二叉链表表示及其遍历

简介: 基本任务:用二叉链表存储结构表示下图所示二叉树, 并用递归方法输出三种遍历结果。修改数节点值的数据类型及visit函数后,可以正常输出进阶任务:1,计算输出所建树的高度2,用非递归算法实现中序遍历3,实现层次遍历,提示见后面。 4,用顺序存储表示,并进行层次遍历、先序、中序和后续遍历5,用非递归算法实现先序遍历、后续遍历

实验目的: 掌握二叉树的链式存储结构及其遍历

实验重点: 二叉树的链式存储实现方法

实验内容

基本任务:用二叉链表存储结构表示下图所示二叉树,

 并用递归方法输出三种遍历结果。

修改数节点值的数据类型及visit函数后,可以正常输出

进阶任务:

1,计算输出所建树的高度

2,用非递归算法实现中序遍历

3,实现层次遍历,提示见后面。

      4,用顺序存储表示,并进行层次遍历、先序、中序和后续遍历

5,用非递归算法实现先序遍历、后续遍历

                     

实验时间:2020年11月10日(周二1,2节)

实验地点:10号楼413

image.gif编辑

实验提示:

进阶任务提示:

1,思想:利用队列的思想,根结点不空则入队,队不空则出队并遍历队首结点,然后分别判断队首结点的左右子树是否为空,不空则入队;直至队列为空。则遍历完成。(为了简单可以采用顺序存储队列)

程序流程图

image.gif编辑

程序代码

#include<stdio.h>
#include<malloc.h> 
#include<stdlib.h> 
#define MaxSize 100 
//#define ERROR 0
//#define OK 1
typedef int DataType;
/*示例:1 2 4 0 0 5 0 0 3 0 0 
  先序:
      1 2 4 5 3 
  中序:
      4 2 5 1 3 
  后续:
      4 5 2 3 1 
  示例:8 3 1 0 0 6 4 0 0 7 0 0 19 14 13 0 0 0 0 
    二叉树的先序序列:
  8 3 1 6 4 7 19 14 13
  二叉树的中序序列:
  1 3 4 6 7 8 13 14 19
  二叉树的后序序列:
  1 4 7 6 3 13 14 19 8
*/ 
DataType all[19]={8,3,1,0,0,6,4,0,0,7,0,0,19,14,13,0,0,0,0};  
int u=0;
typedef struct BiTNode 
{
  DataType data;  
  struct BiTNode *lchild;  
  struct BiTNode *rchild; 
} *BiTree,BitNode; 
typedef struct Queue{
  int first; 
  BitNode*data[MaxSize];
  int final;
}Queue; 
void CreateBitTree(BiTree *T);      /*按照先序输入字符序列递归创建二叉树*/ 
void PreOrderTraverse(BiTree T); /*二叉树的先序遍历的递归函数*/ 
void InOrderTraverse(BiTree T);  /*二叉树的中序遍历的递归函数*/
void PostOrderTraverse(BiTree T); /*二叉树的后序遍历的递归函数*/ 
void PreOrderTraverse2(BiTree T); /*二叉树的先序遍历的非递归函数*/ 
void InOrderTraverse2(BiTree T); /*二叉树的中序遍历的非递归函数*/ 
void PostOrderTraverse2(BiTree T); /*二叉树的后序遍历的非递归函数*/   
void BinaryTreeLeveLOrder(BiTree T);/*二叉树的层次遍历*/ 
bool enQueue(Queue*& q,BitNode*& T);     //入队,层次遍历需求 
bool deQueue(Queue*& q,BitNode*& T);     //出队,层次遍历需求 
bool emptyQueue(Queue*& q);     //判断队列是否为空,层次遍历需求 
int height(BiTree T);/*二叉树的高度*/ 
int main() 
{ 
  BiTree T;    //构建二叉链表表示的二叉树 
  T=NULL;      //给树初始化 
  int i=0;
  printf("按先序序列输入二叉树中结点的值(一个整型)各数字用空格分开,整型0表示空树\n");  
  for(i=0;i<sizeof(all)/sizeof(int);i++)
  printf("%d ",all[i]);
  printf("\n");
  CreateBitTree(&T);  
  printf("二叉树的递归先序序列:\n");  
  PreOrderTraverse(T);  
  printf("\n");  
  printf("二叉树的递归中序序列:\n");  
  InOrderTraverse(T);  
  printf("\n");  
  printf("二叉树的递归后序序列:\n");  
  PostOrderTraverse(T);  
  printf("\n"); 
  printf("二叉树的非递归先序序列:\n");  
  PreOrderTraverse2(T);  
  printf("\n");  
  printf("二叉树的非递归中序序列:\n");  
  InOrderTraverse2(T);  
  printf("\n");  
  printf("二叉树的非递归后序序列:\n");  
  PostOrderTraverse2(T);  
  printf("\n"); 
  printf("二叉树的层次遍历:\n");
  BinaryTreeLeveLOrder(T);
  printf("\n"); 
  printf("二叉树的高度为:\n");
  printf("%d\n",height(T));
}  
void CreateBitTree(BiTree *T) /*递归创建二叉树*/
{  
    DataType ch;     
  //scanf("%d",&ch);  //通过键盘输入进行树的赋值 
  ch=all[u];//通过数组进行对树的赋值
  u++; 
  if(ch==0)  
      *T=NULL;  
  else 
  { 
        *T=(BiTree)malloc(sizeof(BitNode));   /*生成根结点*/ 
        if(!(*T)) 
            exit(-1);        
    (*T)->data=ch; 
        CreateBitTree(&((*T)->lchild));    /*构造左子树*/         
    CreateBitTree(&((*T)->rchild));    /*构造右子树*/ 
    } 
}  
void PreOrderTraverse(BiTree T) /*先序遍历二叉树的递归实现*/ 
{ 
    if(T)
  { 
        printf("%d ",T->data); 
    PreOrderTraverse(T->lchild);
    PreOrderTraverse(T->rchild);
   } 
}
void InOrderTraverse(BiTree T) /*中序遍历二叉树的递归实现*/ 
{ 
    if(T)
  {   
    InOrderTraverse(T->lchild);
    printf("%d ",T->data);
      InOrderTraverse(T->rchild);
    } 
} 
void PostOrderTraverse(BiTree T) /*后序遍历二叉树的递归实现*/ 
{ 
    if(T)          
  {   
    PostOrderTraverse(T->lchild);         
    PostOrderTraverse(T->rchild);    
    printf("%d ",T->data);     
    } 
}  
void PreOrderTraverse2(BiTree T)/*二叉树的先序遍历的非递归函数*/ 
{
  BiTree stack[MaxSize];
  int top=0;
  BitNode *p;
  p=T;
  while(p!=NULL||top>0)
  {
    while(p!=NULL)
    {
      stack[top++]=p;
      printf("%d ",p->data);
      p=p->lchild;
    }
    if(top>0)
    {
      top--;
      p=stack[top];
      p=p->rchild;
    }
  }
} 
void InOrderTraverse2(BiTree T)/*二叉树的中序遍历的非递归函数*/
{
  BiTree stack[MaxSize];
  int top=0;
  BitNode *p;
  p=T;
  while(p!=NULL||top>0)
  {
    while(p!=NULL)
    {
      stack[top++]=p;
      p=p->lchild;
    }
    if(top>0)
    {
      top--;
      p=stack[top];
      printf("%d ",p->data);
      p=p->rchild;
    }
  }
}
void PostOrderTraverse2(BiTree T)/*二叉树的后序遍历的非递归函数*/
{
  BiTree stack[MaxSize];
  int top=0;
  BitNode *p,*q;
  p=T;
  q=NULL;
  while(p!=NULL||top>0)
  {
    while(p!=NULL)
    {
      stack[top++]=p;
      p=p->lchild;
    }
    if(top>0)
    {
      p=stack[top-1];
      if(p->rchild==NULL||p->rchild==q)
      {
        printf("%d ",p->data);
        q=p;
        p=NULL;
        top--;
      }
      else
      p=p->rchild;
    }
  }
}
bool enQueue(Queue*& q,BitNode*& T){     //入队 
  if(q->final==MaxSize-1){
    return false;
  }
  q->final++;
  q->data[q->final]=T;
  return true;
}
bool deQueue(Queue*& q,BitNode*& T){     //出队 
  if(q->first==q->final){
    return false;
  }
  q->first++;
  T=q->data[q->first];
  return true;
}
bool emptyQueue(Queue*& q){     //判断队列是否为空 
  if(q->first==q->final){
    return true;
  }
  else{
    return false;
  }
}
void BinaryTreeLeveLOrder(BiTree T)/*二叉树的层次遍历*/ 
{
  Queue *q;
  int num;
  q=(Queue*)malloc(sizeof(Queue));
  q->first=q->final=-1;
  if(T!=NULL){
    enQueue(q,T);
  }
  while(emptyQueue(q)!=true){
    deQueue(q,T);
    printf("%d ",T->data);
    if(T->lchild!=NULL){
      enQueue(q,T->lchild);
    }
    if(T->rchild!=NULL){
      enQueue(q,T->rchild);
    }
  }
}
int height(BiTree T)/*二叉树的高度*/ 
{ 
  BitNode *p;
  p=T;
  if(p==NULL)
    return 0;
  else
  {
    int lheight=height(p->lchild);
    int rheight=height(p->rchild);
    if(lheight>rheight)
      return(lheight+1);
    else return(rheight+1);
  }
}

image.gif

运行结果及分析

image.gif编辑

上图为通过键盘输入所构建的树,下图为实验要求通过数组依次写入树的每个结点。

image.gif编辑

按先序序列输入二叉树中结点的值(一个整型)各数字用空格分开,整型0表示空树,依次用先序、中序、后序遍历的递归函数实现遍历输出,再依次用先序、中序、后序遍历的非递归函数进行遍历输出,得到以上结果。再利用队列实现二叉树的层次遍历,进行输出。最后输出树的高度。

心得体会

对C语言的链表进行深刻复习,学习到怎么创建树,怎么实现树的遍历的各种方法,同时也进一步复习栈和队列的用法,对算法有了进一步的学习,得以加强。

相关文章
|
8月前
|
存储 机器学习/深度学习 监控
网络管理监控软件的 C# 区间树性能阈值查询算法
针对网络管理监控软件的高效区间查询需求,本文提出基于区间树的优化方案。传统线性遍历效率低,10万条数据查询超800ms,难以满足实时性要求。区间树以平衡二叉搜索树结构,结合节点最大值剪枝策略,将查询复杂度从O(N)降至O(logN+K),显著提升性能。通过C#实现,支持按指标类型分组建树、增量插入与多维度联合查询,在10万记录下查询耗时仅约2.8ms,内存占用降低35%。测试表明,该方案有效解决高负载场景下的响应延迟问题,助力管理员快速定位异常设备,提升运维效率与系统稳定性。
344 4
|
存储 机器学习/深度学习 算法
KMP、Trie树 、AC自动机‌ ,三大算法实现 优雅 过滤 netty 敏感词
KMP、Trie树 、AC自动机‌ ,三大算法实现 优雅 过滤 netty 敏感词
KMP、Trie树 、AC自动机‌ ,三大算法实现 优雅 过滤 netty  敏感词
|
11月前
|
监控 算法 安全
基于 C# 基数树算法的网络屏幕监控敏感词检测技术研究
随着数字化办公和网络交互迅猛发展,网络屏幕监控成为信息安全的关键。基数树(Trie Tree)凭借高效的字符串处理能力,在敏感词检测中表现出色。结合C#语言,可构建高时效、高准确率的敏感词识别模块,提升网络安全防护能力。
274 2
|
监控 算法 数据处理
基于 C++ 的 KD 树算法在监控局域网屏幕中的理论剖析与工程实践研究
本文探讨了KD树在局域网屏幕监控中的应用,通过C++实现其构建与查询功能,显著提升多维数据处理效率。KD树作为一种二叉空间划分结构,适用于屏幕图像特征匹配、异常画面检测及数据压缩传输优化等场景。相比传统方法,基于KD树的方案检索效率提升2-3个数量级,但高维数据退化和动态更新等问题仍需进一步研究。未来可通过融合其他数据结构、引入深度学习及开发增量式更新算法等方式优化性能。
307 17
|
存储 监控 算法
局域网上网记录监控的 C# 基数树算法高效检索方案研究
在企业网络管理与信息安全领域,局域网上网记录监控是维护网络安全、规范网络行为的关键举措。随着企业网络数据量呈指数级增长,如何高效存储和检索上网记录数据成为亟待解决的核心问题。基数树(Trie 树)作为一种独特的数据结构,凭借其在字符串处理方面的卓越性能,为局域网上网记录监控提供了创新的解决方案。本文将深入剖析基数树算法的原理,并通过 C# 语言实现的代码示例,阐述其在局域网上网记录监控场景中的具体应用。
270 7
|
人工智能 算法 语音技术
Video-T1:视频生成实时手术刀!清华腾讯「帧树算法」终结闪烁抖动
清华大学与腾讯联合推出的Video-T1技术,通过测试时扩展(TTS)和Tree-of-Frames方法,显著提升视频生成的连贯性与文本匹配度,为影视制作、游戏开发等领域带来突破性解决方案。
492 4
Video-T1:视频生成实时手术刀!清华腾讯「帧树算法」终结闪烁抖动
|
算法 Java
算法系列之数据结构-Huffman树
Huffman树(哈夫曼树)又称最优二叉树,是一种带权路径长度最短的二叉树,常用于信息传输、数据压缩等方面。它的构造基于字符出现的频率,通过将频率较低的字符组合在一起,最终形成一棵树。在Huffman树中,每个叶节点代表一个字符,而每个字符的编码则是从根节点到叶节点的路径所对应的二进制序列。
440 3
 算法系列之数据结构-Huffman树
|
12月前
|
机器学习/深度学习 算法 搜索推荐
决策树算法如何读懂你的购物心理?一文看懂背后的科学
"你为什么总能收到刚好符合需求的商品推荐?你有没有好奇过,为什么刚浏览过的商品就出现了折扣通知?
342 0
|
存储 机器学习/深度学习 算法
C 408—《数据结构》算法题基础篇—链表(下)
408考研——《数据结构》算法题基础篇之链表(下)。
575 30
|
存储 算法 C语言
C 408—《数据结构》算法题基础篇—链表(上)
408考研——《数据结构》算法题基础篇之链表(上)。
849 25