文件说明

文件名 数据生成.cpp test.cpp BST.h BST.cpp
文件内容 用于生成测试数据的程序 折半查找和测试主程序 BST类声明 BST类实现

1.设计 BST 的左右链存储结构,并实现 BST 插入(建立)、删除、查找和排 序算法。

设计的BST类

#pragma once
#include<fstream>
using namespace std;
#include<string>
#define max 10000typedef struct celltype {int data;celltype* lchild, * rchild;
}BSTNode;//存储结构
typedef BSTNode* BSTREE;
class BST {
public:BST(string filename);//输入文件名构建查找树int bst_insert(BSTREE &T,int k);//插入函数BSTREE bst_search(int k, int& len);//查找int delete_(BSTREE &BT);//辅助删除函数,用于处理继承节点void bst_delete(BSTREE& BT,int k);//删除函数void visit(BSTREE T);//访问节点函数void bst_sort(BSTREE BT);//排序,实质上就是中序遍历void search_cost();//计算平均查找长度查找,只适用于特定数据序列类型public:BSTREE T;//二叉查找树double len_s;//平均查找成功次数double len_f;//平均查找失败长度int f_data[max];//用于保存文件输入流的数据int total;//总结点数
};

插入和建立:

BST::BST(string filename)//输入文件名构建查找树
{ifstream ifs(filename, ios::in);//以读方式打开图文件if (!ifs.is_open()){cout << "文件打开失败" << endl;return;}int num;//输入流承载体int i = 0;total = 0;while (ifs >> num) {//读取文件进数组f_data[i++] = num;}for (int j = 0; j < i; j++)bst_insert(T, f_data[j]);//逐个插入
}int BST::bst_insert(BSTREE &BT,int k)//插入函数
{if (BT == NULL) {//根节点为空BT = new BSTNode;BT->data = k;BT->lchild = NULL;BT->rchild = NULL;total++;return 1;//创建成功,返回1}else if (k == BT->data)return 0;//存在相同关键字,插入失败else if (k < BT->data)//左小return bst_insert(BT->lchild, k);else//右大return bst_insert(BT->rchild, k);
}

查找

BSTREE BST::bst_search(int k, int& len)//查找
{BSTREE p = T;while (p) {len++;if (k == p->data) {cout<< "找到元素:" << p->data <<endl;return p;//找到直接返回}if (k > p->data)p = p->rchild;elsep = p->lchild;}if (p == NULL)cout << "没找到该元素" <<k<< endl;return p;//查找失败返回空
}

删除

int BST::delete_(BSTREE &BT)//辅助删除函数,用于处理继承节点
{//目的是找到中序遍历,ABC,用A中最后一个元素或C中第一个元素替换掉Bint tmp;//这里是找到右边的最小节点if (BT->lchild == NULL) {//没有左子树,是最小的节点tmp = BT->data;BT = BT->rchild;//替换return tmp;}//T就是最小else return delete_(BT->lchild);//有左子树,一直往左下找
}//因为是多重递归,要用return才能返回值到最开始调用函数中void BST::bst_delete(BSTREE& BT,int k)//删除函数
{if (BT != NULL) {if (k < BT->data)bst_delete(BT->lchild, k);//一直往下查找else if (k > BT->data)//不能直接用search,因为返回的是局部变量,如果返回引用的话,又会导致头节点变化bst_delete(BT->rchild, k);else//找到待删除节点if (BT->rchild == NULL) {//右子树为空cout << "成功删除元素:" << BT->data << endl;BT = BT->lchild;total--;}else if (BT->lchild == NULL) {//左子树为空cout << "成功删除元素:" << BT->data << endl;BT = BT->rchild;total--;}else {cout << "成功删除元素:" << BT->data << endl;BT->data = delete_(BT->rchild);total--;}}
}

排序

void BST::visit(BSTREE BT)//访问节点函数
{cout << BT->data << " ";
}void BST::bst_sort(BSTREE BT)//排序,实质上就是中序遍历
{int i = 0;if (BT != NULL) {bst_sort(BT->lchild);visit(BT);bst_sort(BT->rchild);}
}

统计查找长度

void BST::search_cost()//只适用于特定数据序列类型
{int s = 0;//查找成功节点个数int sl = 0;//查找成功总长度int f = 0;//查找失败节点个数int fl = 0;//查找失败总长度for (int i = 0; i <= 2048; ++i) {if (i % 2) {//奇数s++;bst_search(i, sl);}else {f++;bst_search(i, fl);}}len_s = (double)sl / s;len_f = (double)fl / f;cout << "查找成功的平均查找长度为:" << len_s << endl;cout << "查找失败的平均查找长度为:" << len_f << endl;}

建立、插入、查找、删除、排序:

使用数据:(生成源程序下面有)

测试代码:

int main(void) {//测试BST——————————————————BST T1("input1.txt");cout<<"初始总节点数为" << T1.total << endl;int len = 0;T1.bst_search(2047, len);//查2047T1.bst_delete(T1.T,5);//先删5cout << "删除5后总节点数为" << T1.total << endl;int i = 0;T1.bst_search(5,i);//再找5T1.bst_insert(T1.T, 4);//再插入4cout << T1.total << endl;cout << "插入4后总节点数为" << T1.total << endl;T1.bst_sort(T1.T);//T1.search_cost();
}

测试结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-23axrooo-1677332245602)(2022120067-刘虹志-作业5.assets/1.png)]

2.实现折半查找算法。

代码:

int Bin_Search(int a[], int n, int key, int& len) {//折半查找int low = 0, high = n, mid;//这里直接传入BST类中的f_data数组就行了while (low <= high) {mid = (low + high) / 2;len++;if (a[mid] == key)return mid;//返回数组下标else if (a[mid] > key)high = mid - 1;elselow = mid + 1;}return -1;
}

**3.实验比较:设计并产生实验测试数据,考察比较两种查找方法的时间性能, 并与理论结果进行比较。以下具体做法可作为参考: **

(1) 第 1 组测试数据: n=1024 个已排序的整数序列(如 0 至 2048 之间 的奇数);第 2 组测试数据:第 1 组测试数据的随机序列。

生成测试数据:

#include<iostream>
#include<fstream>
#include<cstdlib>
#include <time.h>
using namespace std;
#define max 2048//生成0到2048的奇数序列
int main() {ofstream ofs1("input1.txt");int data[max];int total = 0;for (int i = 0; i <= max; ++i) {if (i % 2) {//第一组。有序奇数序列data[total++] = i;ofs1 << i << " ";//用空格、制表符、或者换行来分割数据,方便输入流读取}}ofs1.close();//第二组。无序奇数序列,把data打乱再输出就行了ofstream ofs2("input2.txt");srand((int)time(NULL));//随机数种子for (int i = 0; i < total; i++) {int index = rand() % total;swap(data[i], data[index]);}while (total--) {ofs2 << data[total] << " ";}ofs2.close();
}

输出结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5scLLRdd-1677332245602)(2022120067-刘虹志-作业5.assets/IL%RVW92PBRB{CFR[0M94_W.png)]

**(2) 以上述两组测试数据作为输入,分别建立 BST 查找结构。 **

建立代码

 BST T1("input1.txt");BST T2("input2.txt");

文件存放位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-exVtMA9D-1677332245603)(2022120067-刘虹志-作业5.assets/图片1.png)]

**(3) 编写程序计算所建的两棵 BST 的查找成功和查找失败的平均查找长度(主要是改造 Search 算法,对“比较”进行计数),并与理论结 果比较。 **

n=1024 个已排序的整数序列测试代码;

 BST T1("input1.txt");T1.search_cost();

实验结果:

n=1024 个已排序的整数序列

实际结果为

查找成功的平均查找长度为:512.5
查找失败的平均查找长度为:512.999

与理论结果相符合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZpSqMkrK-1677332245603)(2022120067-刘虹志-作业5.assets/图片2.png)]

n=1024 个随机的整数序列测试代码;

 BST T2("input2.txt");T2.search_cost();

实验结果:

n=1024 个随机的整数序列

实际结果为

查找成功的平均查找长度为:11.8633
查找失败的平均查找长度为:12.8507

与理论结果相符合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YnqhBnc8-1677332245604)(2022120067-刘虹志-作业5.assets/[DW6%XYG}22C]EH4ZDQH7ST.png)]

(4) 分别以上述 BST 查找结构的中序遍历序列作为折半查找算法的输入,编写程序分别计算折半查找的查找成功和查找失败的平均查找长度,并与理论结果比较。

中序遍历测试代码:

 BST T1("input1.txt");cout <<endl<< "T1的中序序列" << endl;T1.bst_sort(T1.T);BST T2("input2.txt");cout << endl << "T2的中序序列" << endl;T2.bst_sort(T2.T);

结果:二者的中序序列完全相同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2w0qMpIm-1677332245604)(2022120067-刘虹志-作业5.assets/3.png)]

前面已经证明顺序和乱序整数序列的中序输出一样,这里就只用计算一次平均查找长度

折半查找计算长度代码;

 BST T1("input1.txt");int sl = 0;//查找成功总长度int s = 0;//查找成功元素个数int fl = 0;//查找失败总长度int f = 0;//查找失败元素个数for (int i = 0; i <= 2048; ++i) {if (i % 2) {//奇数s++;Bin_Search(T1.f_data, T1.total - 1, i, sl);}else {//偶数f++;Bin_Search(T1.f_data, T1.total - 1, i, fl);}}double len_s = (double)sl / s;double len_f = (double)fl / f;cout << "查找成功的平均查找长度为:" << len_s << endl;cout << "查找失败的平均查找长度为:" << len_f << endl;

折半查找结果:

实际结果

查找成功的平均查找长度为:9.01172
查找失败的平均查找长度为:10.002

与最好情况下的折半查找理论长度基本相同

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mo7Zl9DF-1677332245604)(2022120067-刘虹志-作业5.assets/4.png)]

(5) 以上实验能否说明:就平均性能而言,BST 的查找与折半查找差不多,为什么?

在随机数组情况下,BST的平均查找长度和折半查找差不多,时间效率都为O(logn)。

在有序数组的情况下,BST可能会形成一颗很长的右斜树或者左斜树,这时的时间效率就就和随机情况下差距很大了。

ouble)sl / s;
double len_f = (double)fl / f;
cout << “查找成功的平均查找长度为:” << len_s << endl;
cout << “查找失败的平均查找长度为:” << len_f << endl;


折半查找结果:实际结果查找成功的平均查找长度为:9.01172
查找失败的平均查找长度为:10.002与最好情况下的折半查找理论长度基本相同[外链图片转存中...(img-mo7Zl9DF-1677332245604)]**(5) 以上实验能否说明:就平均性能而言,BST 的查找与折半查找差不多,为什么?**在随机数组情况下,BST的平均查找长度和折半查找差不多,时间效率都为O(logn)。在有序数组的情况下,BST可能会形成一颗很长的右斜树或者左斜树,这时的时间效率就就和随机情况下差距很大了。但是实际上有序数组很少出现,考虑大部分情况,可以认为平均性能上,BST的查找与折半查找差不多。

HIT-哈工大数据结构-作业5(C++)相关推荐

  1. 一元多项式式计算器(哈工大数据结构实验)

    这是哈工大数据结构课的一个实验作业,试验结束了,终于可以发出来了. 实验要求: 实验 1 线性结构及其应用 实验项目:线性表的链式存储结构与应用 实验题目:一元多项式计算器 实验内容: 设计线性表的动 ...

  2. 哈工大计算机网络-作业讲解

    哈工大计算机网络作业 例题等来源于哈工大李全龙老师,李全龙老师YYDS 计算机网络笔记 我们知道分组交换网络中时延共有四种 处理时延 排队时延 传输时延 传播时延 详细讲解

  3. 数据结构作业之输出树的每一条从根节点到叶节点的路径

    数据结构作业,输出树的每一条从根节点到叶节点的路径 #include <stdio.h> #include <stdlib.h> typedef struct tree {ch ...

  4. 数据结构作业9(清览题库)

    数据结构作业9(清览题库) 主要涉及内容为:拓扑排序,关键路径,内排序等

  5. HIT暑假python作业三《超级画板》

    HIT暑假python作业三<超级画板> 作业上交版代码 编译版 程序运行效果**(运行时确保同目录下有文件夹img,里面有pen,eraser,plus,minus四个png图象,如果没 ...

  6. HIT CSAPP大作业论文

    计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 计算机类 学 号 1190201816 班 级 1903012 学 生 樊红雨 指 导 教 师 史先俊 计算机科学与技术学院 20 ...

  7. HIT计算机系统大作业2022

    计算机系统 大作业 计算机科学与技术学院 2021年5月 摘 要 学习计算机系统后,从底层对一个简单的Hello.c如何一步步编译,链接,加载,执行等进行浅层的描述. 关键词:计算机系统,底层. 目 ...

  8. HIT 计算机系统大作业 Hello程序人生P2P

    计算机系统 大作业 题 目 程序人生-Hello's P2P 专 业 人工智能(未来技术模块) 学 号 7203610725 班 级 2036014 学 生 黄鸿睿 指 导 教 师 刘宏伟 计算机科学 ...

  9. 【数据结构作业—01】用单循环链表解决约瑟夫问题

    实验作业一:线性表(链表) 1. 用单循环链表解决约瑟夫问题. 问题描述: 一个旅行社要从n个旅客中选出一名旅客,为他提供免费的环球旅行服务.旅行社安排这些旅客围成一个圆圈,从帽子中取出一张纸条,用上 ...

  10. 数据结构作业(校园导航系统)

    本人是一名暨南大学大二的学生,这是我的数据结构课程的一次编程作业,主要算法是弗洛伊德算法,希望各位大神多多指教. #include<stdio.h> #include<stdlib. ...

最新文章

  1. 零基础入门学习Python(30)-异常处理1
  2. 感知不强又徒增功耗?为何今年5G手机也这么重视AI
  3. mac安装git客户端
  4. SQLite数据库管理工具(SQLiteStudio)v3.1.1
  5. java 学习心得 (近期的)
  6. mysql 基于语句的复制_MySQL 复制 - 性能与扩展性的基石 1:概述及其原理
  7. 使用SWTEventHelper清除SWT侦听器通知
  8. 人脸识别算法-LBP算法及python实现
  9. 虚拟机中标麒麟的网络设置
  10. 《极客与团队》读书记录
  11. 小程序webview内嵌h5链接第二次打开空白
  12. 支付宝支付对账单java_[Java]解析支付宝对账单csv
  13. 交通大数据干货总结(1)
  14. 【oracle11g,13】表空间管理2:undo表空间管理(调优) ,闪回原理
  15. (1)ENVI-met项目介绍
  16. 烽火戏诸侯 《剑来》 最新章节下载阅读,mobi、amz3、epub格式
  17. java异地登录验证_同一帐号异地登录
  18. JAVA字符串中字符类型的识别和分类(汉字、数字、字母、特殊符号等)
  19. 微信小程序使用weapp-qrcode生成二维码
  20. 操作系统 | Mac如何更新word中的域

热门文章

  1. C语言用不同字体标识,c语言中标识符命名规则是怎样的
  2. 【游戏后端】游戏服务器端开发的一些建议(转载)
  3. 取消GitHub邮箱订阅
  4. 桌面图标icon替换客制图标。图标要比原始图标大,要求一致。应用图标去掉四周白边,保持原有比例。
  5. 众盟超级推的“私域营销”,如何实现人人优活的流量十倍增?
  6. Excel后缀名 .xls和.xlsx 有什么区别?
  7. 【QT】linux下alsa库的移植和QT中音视频的处理笔记
  8. HDMI 4K分辨率 时序
  9. Java使用EWS读取exchange邮件和会议信息
  10. ​stp文件转obj