数据结构实验-二叉排序树应用实验报告
- 格式:doc
- 大小:141.00 KB
- 文档页数:15
实 验 报 告
实验课程:数 据 结 构
实验项目:实验四二叉排序树应用
专 业:计算机科学与技术
班 级:
姓 名:
学 号:
指导教师:
目 录
一、问题定义及需求分析
(1)问题描述
(2)实验任务
(3)需求分析
二、概要设计:
(1)抽象数据类型定义
(2)主程序流程
(3) 模块关系
三、详细设计
(1)数据类型及存储结构
(2)模块设计
四、调试分析
(1)调试分析
(2)算法时空分析
(3)经验体会
五、使用说明
(1)程序使用说明
六、测试结果
(1)运行测试结果截图
七、附录
(1)源代码
一、问题定义及需求分析
(1)实验目的
二叉排序树应用
问题描述
互联网域名系统是一个典型的树形层次结构。从根节点往下的第一层是顶层域,如cn、com等,最底层(第四层)是叶子结点,如www等。因此,域名搜索可以构造树的结构完成;
(2)实验任务
设计基于二叉排序树的搜索互联网域名的程序。
(3)需求分析:
1)采用二叉树的二叉链表存储结构。
2)完成二叉排序树的创建、插入、删除、查询操作。
3)可以考虑两棵二叉排序树的合并。
二、概要设计:
(1)抽象数据类型定义:
程序中定义了二叉排序树的节点类型;由数据域和左右孩子指针构成;指针类型为该节点类型,指向该类型的节点形成二叉排序树;数据域是由字符数组构成,用于存储节点数据信息。
(2)主程序流程:
输入域名
拆分域名并完成二叉排序树的创建
调用功能函数进入功能菜单 选择执行不同的操作(查找、插入、删除) 操作完毕后可选择返回功能函数继续执行操作或者结束程序
(3)模块间的调用关系:
创建二叉排序树
功能函数
查找 插入 删除
选择
结束
三、详细设计
采用二叉链表存储结构的二叉排序树的定义如下:
typedef struct BiTNode
{
ElemType data[30]; //定义数据域类型为字符数组
struct BiTNode *lchild, *rchild; //定义左右孩子节点指针
}BiTNode, *BiTree;
模块1-查找树中是否有待插入节点
算法如下:
int SearchBST(BiTree T, char *key, BiTree f, BiTree *p)
{
if (!T) /* 查找不成功 */
{
*p = f;
return 0;
}
else if(strcmp(key,T->data)==0) /* 查找成功 */
{
*p = T;
return 1;
}
else if (strcmp(key,T->data)<0)
return SearchBST(T->lchild, key, T, p); /* 若该节点小于当前节点,则在左子树中继续查找 */
else
return SearchBST(T->rchild, key, T, p); /* 否则在右子树中继续查找 */
}
模块2-插入节点
算法如下:
int InsertBST(BiTree *T, char *key)
{
BiTree p,s;
if (!SearchBST(*T, key, NULL, &p)) /* 查找不成功 */
{
s = (BiTNode*)malloc(sizeof(BiTNode));
strcpy(s->data, key);
s->lchild = s->rchild = NULL;
if (!p)
*T = s; /* 插入s为新的根结点 */
else if (strcmp(key,p->data)<0)
p->lchild = s; /* 插入s为左孩子 */ else
p->rchild = s; /* 插入s为右孩子 */
return 1;
}
else
return 0; /* 树中已有关键字相同的结点,不再插入 */
}
模块3-删除节点
算法如下:
int Delete(BiTree *p)
{
BiTree q,s;
if((*p)->rchild==NULL) /* 右子树空则只需重接它的左子树(待删结点是叶子也走此分支)
*/
{
q=*p;
*p=(*p)->lchild;
free(q);
}
else if((*p)->lchild==NULL) /* 只需重接它的右子树 */
{
q=*p;
*p=(*p)->rchild;
free(q);
}
else /* 左右子树均不空 */
{
q=*p;
s=(*p)->lchild;
while(s->rchild) /* 转左,然后向右到尽头(找待删结点的前驱) */
{
q=s;
s=s->rchild;
}
strcpy((*p)->data,s->data); /* s指向被删结点的直接前驱(将被删结点前驱的值取代被删结点的值) */
if(q!=*p)
q->rchild=s->lchild; /* 重接q的右子树 */
else
q->lchild=s->lchild; /* 重接q的左子树 */
free(s);
}
return 1;
} 模块4-查找待删除节点的位置
算法如下:
int DeleteBST(BiTree *T,char *key)
{
if(!*T) /* 不存在关键字等于key的数据元素 */
return 0;
else
{
if (strcmp(key,(*T)->data)==0) /* 找到关键字等于key的数据元素 */
return Delete(T);
else if (strcmp(key,(*T)->data)<0)
return DeleteBST(&(*T)->lchild,key);/* 若待删除节点大于当前节点,则递归访问其左子树 */
else
return DeleteBST(&(*T)->rchild,key);/* 否则访问右子树 */
}
}
模块5-功能函数包括查找、插入和删除
算法如下:
void Gongneng(BiTNode *A)
{// 执行操作需将此树的根节点传入到此函数里面
int k;
char a[30],c[30],d[30];
printf("请选择你的操作:\n");
printf("1-查找\n");
printf("2-删除\n");
printf("3-插入\n");
printf("输入:");
scanf("%d",&k);
switch(k)
{//通过switch语句执行不同的操作
case 1 :
system("cls");
printf("请输入你要查找的节点:");
scanf("%s",c);
Search(A, c); //调用查找函数
break;
case 2:
system("cls");
printf("请输入你要删除的节点:");
scanf("%s",a);
if(!DeleteBST(&A,a)) printf("\n不存在此节点!\n");
else
{printf("\n删除节点成功!\n\n删除后树的中序遍历结果如下:\n");
InOrder(A);}
break;
case 3:
system("cls");
printf("请输入要插入的节点:");
scanf("%s",d);
if(!InsertBST(&A,d))
printf("插入失败!要插入的节点已存在!\n");
else
{
printf("\n插入成功!\n\n插入后树的中序遍历结果如下:\n");
InOrder(A);
}
break;
default : printf("输入数值错误!\n");
}
}
四、调试分析
问题及解决方法:
在编写功能函数时,在参数的传递上出现了问题;无法正确的将根节点传入到功能函数里,导致功能函数无法正常运行;解决方法为:void Gongneng(BiTNode *A);
时空分析:
由于采用二叉链表的存储结构,所以在插入和删除算法的时间复杂度较低;而对于较多的数据元素形成的树时,查找算法在时间复杂度上不算简便;而存储方面,二叉链表构成的二叉排序树存储较为方便且空间利用率高;
经验体会:
二叉链表存储结构的存储密度较高,使用起来较为方便;而且在处理数据方面,二叉链表存储结构的处理性比较好,尤其是对插入和删除算法;
五、使用说明
第一步:点击运行按钮;
第二步: 输入待输入的域名个数k;
第三步:依次输入k个域名;
第四步:回车,程序跳转至功能界面,根据提示输入想要执行的功能选项序号;
第五步:回车后,针对各功能项有提示药查找、插入或者删除的节点;
第六步: 执行功能后,选择结束运行还是继续操作;
第七步:若选择继续操作,则程序进入功能界面,可继续选择执行的功能;
第八步:循环执行第四到七步;