数据结构与算法-实验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语言的链表进行深刻复习,学习到怎么创建树,怎么实现树的遍历的各种方法,同时也进一步复习栈和队列的用法,对算法有了进一步的学习,得以加强。

相关文章
|
1月前
|
存储 算法 编译器
数据结构实验之矩阵的运算器(二维数组)
本实验旨在通过团队合作,掌握数组和矩阵相关运算的代码实现,包括矩阵的加减、数乘、转置、乘法、n次方及行列式的计算。实验过程中,成员们需分工协作,解决编程难题,最终实现一个功能完备的矩阵计算器。通过本实验,不仅锻炼了编程能力,还加深了对数学概念的理解,同时培养了团队合作精神。
57 4
|
1月前
数据结构实验之串模式匹配问题
本实验旨在掌握串模式匹配技术,通过创建文本文件、实现单词计数与定位功能,最终构建一个包含文件建立、单词统计与定位、程序退出等选项的主菜单,以增强对字符串处理的理解与应用能力。
44 4
|
1月前
|
算法
数据结构实验之最长公共子序列
本实验旨在通过编程实践帮助学生理解串的基本概念及求解最长公共子序列的算法。实验内容包括使用动态规划方法设计并实现算法,以找出给定两序列的最大公共子序列。示例代码展示了如何通过构建状态矩阵和回溯路径来找到解决方案。实验总结指出,`memset()`函数用于内存初始化,且对于特定输入,程序能正确输出最长公共子序列之一。
52 4
|
1月前
|
算法
数据结构实验之操作系统打印机管理器问题
本实验旨在通过实现操作系统中的打印机管理器问题,掌握队列的基本操作如入队、出队等,利用队列的先进先出特性解决先申请先打印的问题。实验包括队列的初始化、入队、出队、打印队列内容等功能,并通过菜单式界面进行交互。实验结果显示基本功能可正常执行,但在连续操作时存在执行失败的情况,需进一步优化。
41 4
|
1月前
|
存储 算法 Perl
数据结构实验之链表
本实验旨在掌握线性表中元素的前驱、后续概念及链表的建立、插入、删除等算法,并分析时间复杂度,理解链表特点。实验内容包括循环链表应用(约瑟夫回环问题)、删除单链表中重复节点及双向循环链表的设计与实现。通过编程实践,加深对链表数据结构的理解和应用能力。
54 4
|
23天前
|
存储 缓存 算法
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式
在C语言中,数据结构是构建高效程序的基石。本文探讨了数组、链表、栈、队列、树和图等常见数据结构的特点、应用及实现方式,强调了合理选择数据结构的重要性,并通过案例分析展示了其在实际项目中的应用,旨在帮助读者提升编程能力。
44 5
|
1月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
81 4
|
1月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
51 4
|
1月前
|
存储 C语言
【数据结构】手把手教你单链表(c语言)(附源码)
本文介绍了单链表的基本概念、结构定义及其实现方法。单链表是一种内存地址不连续但逻辑顺序连续的数据结构,每个节点包含数据域和指针域。文章详细讲解了单链表的常见操作,如头插、尾插、头删、尾删、查找、指定位置插入和删除等,并提供了完整的C语言代码示例。通过学习单链表,可以更好地理解数据结构的底层逻辑,提高编程能力。
85 4
|
1月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
下一篇
DataWorks