《数据结构》实验报告(六)之二叉树的相关操作

二、实验内容

实验题1:实现二叉树各种基本运算的算法

内容:编写一个程序,完成如下功能:

(1)由如图1所示的二叉树创建对应的二叉链存储结构b,该二叉树的括号表示串为“A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))”;

(2)输出二叉树b;

(3)输出‘H’结点的左、右孩子结点值;

(4)输出二叉树b的高度;

实验题2:实现二叉树各种遍历算法。    

内容:编写一个程序,实现二叉树的先序遍历、中序遍历和后序遍历的递归算法,并对图1所示的二叉树b给出求解结果。

实验题3:求二叉树中的结点个数、叶子结点个数

内容:编写一个程序,实现如下功能,并对图1的二叉树进行验证:

(1)输出二叉树b的结点个数;

(2)输出二叉树b的叶子结点个数。

程序代码:(不允许粘图,重点语句加上注释)

实验题1

#include <stdio.h>

#include <malloc.h>

#define STACK_INIT_SIZE 100//存储空间初始分配量

typedef struct node

{

  int data;         //数据元素

  struct node* lchild,* rchild;   //指向左右孩子节点

} BTNode,BiTree;

//建立二叉树

void CreateBTree(BTNode*& T, const char* str)

{

  BTNode* St[STACK_INIT_SIZE], * p = NULL;

  int top = -1, k, j = 0;    

  char ch;  

  T = NULL;            //建立的二叉树初始时为空

  ch = str[j]; 

  while (ch != '\0'//str未扫描完时循环 

  {

     switch (ch)

     {

     case '(':top++; St[top] = p; k = 1;

         break;     //为左孩子节点      

     case ')':top--;

         break;

     case ',':k = 2;

         break;                             //为孩子节点右节点      

     default:p = (BTNode*)malloc(sizeof(BTNode));

         p->data = ch;

         p->lchild = p->rchild = NULL;

         if (T == NULL)                        //*p为二叉树的根节点              

            T = p;

         else                            //已建立二叉树根节点           

         {

            switch (k)

            {

            case 1:St[top]->lchild = p;

                break;

            case 2:St[top]->rchild = p;

                break;

            }

         }

     }      j++;

     ch = str[j];

  }

}

BTNode* FindNode(BTNode* T, int x)

{

  BTNode* p;

  if (T == NULL)

     return NULL;

  else if (T->data == x)

     return T;

  else {

     p = FindNode(T->lchild, x);

     if (p != NULL)

         return p;

     else

         return FindNode(T->rchild, x);

  }

}

BTNode* LchildNode(BTNode* p) //返回左子树

{

  return p->lchild;

}

BTNode* RchildNode(BTNode* p) //返回右子树

{

  return p->rchild;

}

int Height(BTNode* T) //求二叉树的高度

{

  int lchildh, rchildh;

  if (T == NULL) return(0);   //空树的高度为0     

  else

  {

     lchildh = Height(T->lchild);    //求左子树的高度为

     rchildh = Height(T->rchild);    //求右子树的高度为

     return (lchildh > rchildh) ? (lchildh + 1) : (rchildh + 1);

  }

}

void DispBTree(BTNode* T)

{

  if (T != NULL)

  {

     printf("%c", T->data);

     if (T->lchild != NULL || T->rchild != NULL)

     {

         printf("(");  //有孩子节点时才输出

         DispBTree(T->lchild);  //递归处理左子树         

         if (T->rchild != NULL) printf(",");  //有右孩子节点时才输出,          

         DispBTree(T->rchild);  //递归处理右子树         

         printf(")");  //有孩子节点时才输出)      

     }

  }

}

int main()

{

  BTNode* T;

  int height;

  CreateBTree(T, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");//二叉树创建

  printf("输入二叉树的括号表示串\n");

  DispBTree(T);

  printf("\n");

  printf("H结点的左孩子结点值:%c\n", LchildNode(FindNode(T, 'H'))->data);

  printf("H结点的右孩子结点值:%c\n", RchildNode(FindNode(T, 'H'))->data);

  height = Height(T);

  printf("二叉树T的高度 %d\n", height);

}

实验题2

//先序遍历

void PreOrder(BTNode *T)

{

  if(T!=NULL)

  {

     printf("%c ",T->data);

     PreOrder(T->lchild);

     PreOrder(T->rchild);

  }

}

//中序遍历

void InOrder(BTNode *T)

{

  if(T!=NULL)

  {

     InOrder(T->lchild);

     printf("%c ",T->data);

     InOrder(T->rchild);

  }

 }

//后序遍历

void PostOrder(BTNode *T)

{

  if(T!=NULL)

  {

     PostOrder(T->lchild);

     PostOrder(T->rchild);

     printf("%c ",T->data);

  }

 }

int main()

{

  BTNode* T;

  int height;

  CreateBTree(T, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");//二叉树创建

  printf("输入二叉树的括号表示串\n");

  DispBTree(T);

  printf("\n");

  /*printf("H结点的左孩子结点值:%c\n", LchildNode(FindNode(T, 'H'))->data);

  printf("H结点的右孩子结点值:%c\n", RchildNode(FindNode(T, 'H'))->data);

  height = BTHeight(T);

  printf("二叉树T的高度 %d\n", height);*/

  printf("先序遍历结果为:\n");

    PreOrder(T); 

  printf("\n");

  printf("中序遍历结果为:\n");

    InOrder(T); 

  printf("\n");

  printf("后序遍历结果为:\n");

    PostOrder(T); 

    return 0; 

}

实验题3

//结点个数

int Nodes(BTNode *T)

{

  int num1,num2;

  if(T==NULL)

     return 0;

  else

     return Nodes(T->lchild)+Nodes(T->rchild)+1;

 }

//叶子结点个数

int LeafNodes(BTNode *T)

{

  if(!T)      

   return 0;      //空树,无叶子

  else if(!T->lchild && !T->rchild)

           return 1;

        else

           return (LeafNodes(T->lchild) + LeafNodes(T->rchild));

}

int main()

{

  BTNode* T;

  int height;

  CreateBTree(T, "A(B(D,E(H(J,K(L,M(,N))))),C(F,G(,I)))");//二叉树创建

  printf("输入二叉树的括号表示串\n");

  DispBTree(T);

  /*printf("H结点的左孩子结点值:%c\n", LchildNode(FindNode(T, 'H'))->data);

  printf("H结点的右孩子结点值:%c\n", RchildNode(FindNode(T, 'H'))->data);

  height = BTHeight(T);

  printf("二叉树T的高度 %d\n", height);

  printf("先序遍历结果为:\n");

    PreOrder(T); 

  printf("\n");

  printf("中序遍历结果为:\n");

    InOrder(T); 

  printf("\n");

  printf("后序遍历结果为:\n");

    PostOrder(T); 

    return 0; */

  printf("\n树的结点数是%d", Nodes(T));

  printf("\n树的叶子数是%d", LeafNodes(T));

}

程序测试及运行结果:

分析与讨论:

        三种遍历算法的递归算法不同之处仅在于访问根结点和遍历左、右子树的先后关系,需要注意的是,任何一棵二叉树的叶子结点在先序,中序,后序遍历中,其访问的相对次序不变,包括双序遍历仅是在先序遍历的基础上,在访问右子树之前再次访问根结点;通过本次试验,我更好的掌握了二叉树的逻辑结构、二叉树的二叉链表存储结构以及基于二叉链表存储的二叉树遍历操作的实现。在试验的过程中应注意局部变量和全局变量的使用,否则很容易出错,还要注意if和 while 的用法,分清if和 else的嵌套关系。我发现自己存在一些不足,例如不懂得检查错误,经常不理解编译时提示的错误是什么意思,写代码是有点粗心,一条语句后面经常漏掉分号,以后我会以大量的练习、操作来弥补自己的缺点,力求能熟练、迅速地写出一些基本的算法设计。

  • 27
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是数据结构叉树实验报告。 一、实验目的 1. 了解二叉树的概念、性质和基本操作; 2. 掌握二叉树的遍历算法; 3. 实现二叉树的建立、遍历和查找等基本操作。 二、实验原理 二叉树是一种树形结构,它的每个节点最多有两个子节点。二叉树的性质如下: 1. 每个节点最多有两个子节点,分别称为左子节点和右子节点; 2. 左子树和右子树都是二叉树; 3. 空树也是一棵二叉树。 二叉树的遍历有三种方式: 1. 先序遍历:先访问根节点,然后遍历左子树,最后遍历右子树; 2. 中序遍历:先遍历左子树,然后访问根节点,最后遍历右子树; 3. 后序遍历:先遍历左子树,然后遍历右子树,最后访问根节点。 三、实验步骤 本次实验我们将实现二叉树的建立、遍历和查找等基本操作。 1. 定义二叉树结构体。 ```c typedef struct Node { int data; struct Node *left; struct Node *right; } Node, *pNode; ``` 2. 实现二叉树的创建函数。 ```c pNode createTree() { int data; scanf("%d", &data); if(data == -1) { return NULL; } else { pNode node = (pNode)malloc(sizeof(Node)); node->data = data; node->left = createTree(); node->right = createTree(); return node; } } ``` 3. 实现二叉树的先序遍历函数。 ```c void preOrder(pNode node) { if(node != NULL) { printf("%d ", node->data); preOrder(node->left); preOrder(node->right); } } ``` 4. 实现二叉树的中序遍历函数。 ```c void inOrder(pNode node) { if(node != NULL) { inOrder(node->left); printf("%d ", node->data); inOrder(node->right); } } ``` 5. 实现二叉树的后序遍历函数。 ```c void postOrder(pNode node) { if(node != NULL) { postOrder(node->left); postOrder(node->right); printf("%d ", node->data); } } ``` 6. 实现二叉树的查找函数。 ```c pNode search(pNode node, int data) { if(node == NULL) { return NULL; } else if(node->data == data) { return node; } else if(node->data > data) { return search(node->left, data); } else { return search(node->right, data); } } ``` 7. 编写主函数进行测试。 ```c int main() { pNode root = createTree(); printf("先序遍历结果:"); preOrder(root); printf("\n中序遍历结果:"); inOrder(root); printf("\n后序遍历结果:"); postOrder(root); printf("\n请输入要查找的节点值:"); int data; scanf("%d", &data); pNode node = search(root, data); if(node == NULL) { printf("未找到该节点!"); } else { printf("已找到该节点,节点值为:%d", node->data); } return 0; } ``` 四、实验结果 经过测试,程序能够正确地实现二叉树的建立、遍历和查找等基本操作。 五、实验总结 通过本次实验,我们深入理解了二叉树的概念、性质和基本操作,并实现了二叉树的建立、遍历和查找等基本操作。同时,也加深了对指针和动态内存分配的理解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

了一li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值