【数据结构】 实验报告10 顺序、链式存储结构的二叉树递归遍历、层次遍历求高度
一、实验目的和要求 (源码在最后)
要求:
两种及以上存储结构(建议 顺序存储结构和链式存储结构各一)、两种及以上方法(建议 递归遍历和层次遍历方法各一)。分析各代码性能。
抽象数据类型(二叉树)独立模块实现。
其它要求同作业-01要求。
二、实验环境
软件环境:visual stdio 2017
硬件环境:①CPU:Intel(R)Core(TM)i7-8565U CPU @1.80Ghz
②内存:8.0GB
三、实验内容
设计算法并实现求解二叉树高度(深度)。
四、实验过程
4.1 任务定义和问题分析
本次实验需要解决的问题主要为一下三个问题:数据结构的构建,递归遍历的实现,层次遍历的实现。
4.2 数据结构的选择和概要设计
方案一:
顺序存储结构,用一个数组记录二叉树结点值,数组下标记录二叉树编号(下标从1开始用)。递归遍历直接递归,层次遍历直接按层以编号顺序将编号与值一并输出。最终求得高度。
方案二:
链式存储结构,用结构体记录二叉树各结点。递归遍历直接递归,层次遍历以队列为辅助工具,不断入队,出队,达到层次遍历的目的。最终求得高度。
4.3 详细设计
方案一:
①数据结构的构建:
设计成一个class,其中负责记录结点值的数组,其下标为1记录根值,一般的,对于整数i,第2i位(如果存在)为第i位左子结点,2i+1位(如果存在)为第i位右子结点。
②递归遍历的实现:
设计一个递归函数,传入参数为结点标记值i(缺省值为1)其终止条件为:第i位对应结点不存在,返回0。其他情况每次返回各子树的左子树长度和右子树长度的最大值+1。
int GetlengthByRecursion(int i = 1){if (i > totalnum || array[i] == ' ') return 0;return max(GetlengthByRecursion(2 * i), GetlengthByRecursion(2 * i + 1)) + 1;}
③层次遍历的实现:
循环输出各层,即输出各层数组值,同时得到二叉树的高度。
方案二:
①数据结构的构建:
设计成一个struct,内有data记录结点值,leftson指针作为左儿子结点指针,rightson指针作为右儿子结点指针。
②递归遍历的实现:
设计一个递归函数,思路同方案一。
③层次遍历的实现:
先定义好一个队列(同样采用链式结构),该队列用来作为二叉树结点的储存结构。先让根结点入队,之后进入一个循环:以len记录当前队列长度,再次进入循环:循环从1->len,队列头元素出队,记为node,输出node结点的数据,再将node的左儿子、右儿子依次入队。
这样,一个大循环中的小循环便是以层的形式,输出一个二叉树。每进行一次这样的循环,二叉树的高度便+1。
五、测试及结果分析
5.1 实验数据
以该二叉树来测试算法是否有效。
5.2 结果及分析
(中序遍历,先序遍历,后序遍历,这些是实验中的中间产物,保留下来,没有去除)
实验后分析:在采用顺序结构存储二叉树时,具有明显的问题:若二叉树不是完全二叉树形式,为了保持结点之间的关系,不得不空出许多元素来,这就造成了空间的浪费。在极端情况下,仅有n个结点的二叉树,却需要2^n-1个元素空间,这显然是不能接受的。顺序存储结构的优点在于其遍历较快,当然,这也需要在二叉树是完全二叉树时才能体现出来。
而链式存储结构,我们不需要关心二叉树是否为完全二叉树,因为链式存储结构本身的递归特性,其对每一个结点的操作都是相同的。
因此,我认为,在建立一般的二叉树时采用链式结构较为方便,建立完全二叉树时采用顺序存储结构更为方便。
六、实验收获
通过本次实验,加深了我对二叉树的理解,让我学会了如何构建一个二叉树,同时也对顺序结构与链式结构的优缺点理解更深。编程水平也得到了一定的提升。
七、附录(源代码)
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;//顺序存储结构
template<typename T>
class SeqBT
{
public:SeqBT(int totalnum) {if (totalnum > 0){this->totalnum = totalnum;array = new T[totalnum + 1];memset(array, ' ', (totalnum + 1) * sizeof(T));}}~SeqBT(){delete[]array;}void insert(int num, T data){if (num <= totalnum)array[num] = data;}int GetlengthByRecursion(int i = 1){if (i > totalnum || array[i] == ' ') return 0;return max(GetlengthByRecursion(2 * i), GetlengthByRecursion(2 * i + 1)) + 1;}int GetlengthByLevel(){int length = 0;for (; pow(2.0, length+1) - 1 <= totalnum; length++){cout << "第" << length + 1 << "层的元素为:";for (int i = pow(2.0, length); i <= pow(2.0, length + 1) - 1; i++)cout << i << ":" << array[i] << " ";cout << endl;}return length;}
private:int totalnum;T* array;
};
//链式存储结构
template<typename T>
struct TreeNode
{T data;TreeNode<T>* leftson;TreeNode<T>* rightson;TreeNode(){leftson = NULL;rightson = NULL;}
};
//二叉树结点链表(用于队列)
template<typename T>
struct Node
{TreeNode<T>* data;Node* next;Node(){data = NULL;next = NULL;}
};
//层次遍历需要用到的队列(简单设计)
template<typename T>
class queue
{
public:queue(){head = new Node<T>;rear = head;length = 0;}int getlength(){return length;}void push(TreeNode<T>* a){Node<T>* s = new Node<T>;rear->next = s;s->data = a;rear = s;length++;}void pop(TreeNode<T>* & a){Node<T>* s = new Node<T>;s = head->next;a = s->data;head->next = s->next;delete s;if (head->next == NULL){rear = head;}length--;}
private:Node<T>* head;Node<T>* rear;int length;
};
//中序遍历算法
template<typename T>
void Inorder(TreeNode<T>*tree)
{if (tree == NULL) return;if (tree->leftson != NULL)Inorder(tree->leftson);cout << tree->data << " ";if (tree->rightson != NULL)Inorder(tree->rightson);
}
//先序遍历算法
template<typename T>
void Preorder(TreeNode<T>*tree)
{if (tree == NULL) return;cout << tree->data << " ";if (tree->leftson != NULL)Preorder(tree->leftson);if (tree->rightson != NULL)Preorder(tree->rightson);
}
//后续遍历算法
template<typename T>
void Postorder(TreeNode<T>*tree)
{if (tree == NULL) return;if (tree->leftson != NULL)Postorder(tree->leftson);if (tree->rightson != NULL)Postorder(tree->rightson);cout << tree->data << " ";
}
//递归遍历求高度算法
template<typename T>
int GetlengthByRecursion(TreeNode<T>*tree)
{if (tree == NULL)return 0;return max(GetlengthByRecursion(tree->leftson), GetlengthByRecursion(tree->rightson)) + 1;
}
//层次遍历求高度算法
template<typename T>
int GetlengthByLevel(TreeNode<T>* tree)
{queue<T> Queue;Queue.push(tree);int length = 0;while (Queue.getlength()!=0){ cout << "第" << length + 1 << "层元素:";int len = Queue.getlength();for (int i = 1; i <= len; i++){TreeNode<T>* node;Queue.pop(node);cout << node->data << " ";if (node->leftson != NULL) Queue.push(node->leftson);if (node->rightson != NULL) Queue.push(node->rightson); }cout << endl;length++;}return length;
}
int main()
{//顺序存储结构的二叉树的创建cout << "顺式存储结构:" << endl;SeqBT<char> sequenceBT(15);sequenceBT.insert(1, 'A');sequenceBT.insert(2, 'B');sequenceBT.insert(3, 'E');sequenceBT.insert(4, 'C');sequenceBT.insert(5, 'D');sequenceBT.insert(7, 'F');sequenceBT.insert(14, 'G');//递归遍历cout << "递归遍历求高度:" << endl;cout << sequenceBT.GetlengthByRecursion() << endl;//层次遍历cout << "层次遍历求高度:" << endl;cout << sequenceBT.GetlengthByLevel();for (int i = 0; i <= 4; i++) cout << endl;//链式存储结构的二叉树的创建cout << "链式存储结构:" << endl;TreeNode<char>A, B, C, D, E, F, G;A.data = 'A';B.data = 'B';C.data = 'C';D.data = 'D';E.data = 'E';F.data = 'F';G.data = 'G';A.leftson = &B;A.rightson = &E;B.leftson = &C;B.rightson = &D;E.rightson = &F;F.leftson = &G;TreeNode<char>*root = &A;//中序遍历cout << "中序遍历:";Inorder(root);cout << endl;//先序遍历cout << "先序遍历:";Preorder(root);cout << endl;//后序遍历cout << "后序遍历:";Postorder(root);cout << endl;//递归遍历cout << "递归遍历求得高度为:";cout << GetlengthByRecursion(root) << endl;//层次遍历cout << "对二叉树进行层次遍历并得到高度:" << endl;cout << GetlengthByLevel(root) << endl;}
【数据结构】 实验报告10 顺序、链式存储结构的二叉树递归遍历、层次遍历求高度相关推荐
- Python 数据结构 之 线性表 的链式存储结构
用Python 来实现 C语言中 线性表的链式存储结构. 文章转载请注明: Python 数据结构 之 线性表 的链式存储结构 代码地址 https://github.com/WenkeZhou/P ...
- 数据结构与算法——栈的链式存储结构及实现
目录 前言 一.栈的链式储存结构 二.栈的链式储存结构的操作 2.1 进栈操作 2.2 出栈操作 总结 前言 讲完了栈的顺序储存结构,我们现在来看看栈的链式存储结构,简称为链栈. 由于单链表中 ...
- 数据结构4-----线性表的链式存储结构(2)
单链表的题目: 1.单链表的反转 思路:借助三个指针p1,p2,p3.让p1=head;p2=p1->nect;p3=p2->next;之后将p2->next=p1;然后将p1,p2 ...
- 在链式存储结构建立二叉树排序树
#include <stdlib.h> #include <stdio.h>//定义树 typedef struct node{ //树的结点int data;struct n ...
- C语言手写二叉树(链式存储结构)
C语言手写二叉树(链式存储结构) 二叉树结构 二叉树基本运算 代码 图例(main函数执行过程如下:) 阶段I 阶段II 阶段III 阶段IV 阶段V 先序遍历输出过程 二叉树结构 二叉树可以用顺序存 ...
- 数据结构---线性表的静态/动态分配与顺序/链式存储
线性表---基于严魏敏版数据结构c语言实现---谭浩强版c语言 数据元素在计算机中的存储分为顺序存储和链式存储 顺序存储:借助元素在存储器中的相对位置来表示数据元素之间的逻辑关系 链式存储:借助指示元 ...
- 数据结构(二):线性表包括顺序存储结构(顺序表、顺序队列和顺序栈)和链式存储结构(链表、链队列和链栈)...
还记得数据结构这个经典的分类图吧: 今天主要关注一下线性表. 什么是线性表 线性表的划分是从数据的逻辑结构上进行的.线性指的是在数据的逻辑结构上是线性的.即在数据元素的非空有限集中 (1) 存在唯一的 ...
- 实验一 链式存储结构的基本操作
广州大学学生实验报告 开课实验室:计算机科学与工程实验(电子楼418A) 2019年4月27日 学院 计算机科学与教育软件学院 年级.专业.班 计算机科学与技术172班 姓名 xxx 学号 17061 ...
- 数据结构和算法:(3)3.2线性表的链式存储结构
线性表的链式存储结构的特点是用一组任意的存储单元存储线性表的数据元素也就是说你这个可以放在A地点,这个可以放在E地点,A地点和E地点中间可以隔开一个C地点和D地点,这样是允许的),这组存储单元可以存在 ...
最新文章
- java hdfs 新建目录_如何用java在hdfs中创建一个新目录?
- [数据库] Navicat for Oracle设置唯一性和递增序列实验
- 选择让孩子练习羽毛球的家长好好看看!
- The credentials you provided during SQL Server 2008 install are invalid
- 搭配对比学习,万能的 prompt 还能做可控文本生成
- 小程序使用css变量,小程序使用css变量实现“换肤”方案
- javascript对象序列化(对象与JSON字符串的互换)
- 如何切换计算机用户界面,让我来教大家从WIN10界面切换到WIN 7界面吧!嘻嘻
- linux——shell脚本开启新终端
- 建立Socket Policy服务器
- c#调用c++dll找不到入口点,一秒搞定
- 【渝粤教育】国家开放大学2018年春季 0631-21T动物常见病防治 参考试题
- 如何在windows2008/2012上安装启明星系统。
- 【2018华科机试】十二进制
- 用javascript实现一个打乱文字小程序
- 人不成熟的几大特征-----海尔集团CEO张瑞敏演讲稿
- C语言图书管理系统[2023-01-06]
- Apache的winnt_accept: Asynchronous AcceptEx failed问题
- VxWorks中文FAQ(转载)
- 常见3D打印技术原理及比较
热门文章
- 语音播报(播报本地音频文件)实现收款金额的播报
- 基于MSP430G2231实现的频率计
- Dubbo负载均衡的源码流程(2022.5.30)
- php转nodejs 代码,NodeJS实现视频转码的示例代码
- 微信小程序接入Vant Weapp
- 重装系统后mysql数据恢复
- Java Web培训课程一期项目视频发布
- 华为3g网卡 linux,华为Huawei E1550 HSDPA 3G网卡在Ubuntu 10.04 LTS中的使用
- android平台上的移动SNS(一)
- android即时通信和sns,基于Android平台的实时SNS系统设计与实现