数据结构实验-二叉排序树应用实验报告

合集下载

数据结构试验报告 二叉排序树的操作

数据结构试验报告 二叉排序树的操作

数据结构实验报告班级:信息与计算科学专业1102班学号: 1108060214姓名:朱晓东设计日期:2013.6.6西安科技大学计算机学院1.实验报告编写一个演示运用二叉排序树进行数据的的排序、插入、删除、查找等操作的程序。

2.需求分析本演示程序用vc6.0编写,完成数据的排序功能,同时能够进行数据的创建、插入、删除、查找。

(1)输入的形式和输入值的范围:创建二叉排序树时输入较多的值;插入元素时需要输入插入的元素的值;删除元素时输入元素的值;查找操作时需要输入元素的值。

所有输入中,元素的值都是整数。

(2)输出的形式:在创建、插入、删除的操作后,均显示操作后的元素的排序状况,有小到大排序。

(3)程序所能达到的功能:完成二叉排序树的生成、插入、删除、查找操作。

(4)测试数据:①插入操作中依次输入10 9 11 8 12 0(本程序是以0元素为为结束标志);②查找操作中输入13;③插入操作中输入13;3概要设计本程序包含8个函数:(1)主函数main()(2)创建二叉排序树函数BSTCreate(BiTree* bt)(3)显示操作菜单函数menu()(4)显示二叉排序树的内容函数BSTShow(BiTree bt)(5)插入元素函数BSTInsert(BiTree* bt,DataType key)(6)删除元素函数BSTDelete(BiTree* bt,DataType key)(7)查找元素函数BSTSearch(BiTree bt,DataType key)(8)查找要删除的元素的函数DeleteNode(BiTree* bt)各函数之间的关系如下:BSTCreate(BiTree* bt)menu()BSTShow(BiTree bt)mainBSTInsert(BiTree* bt,DataType key)BSTDelete(BiTree* bt,DataType key) DeleteNode(BiTree* bt)BSTSearch(BiTree bt,DataType key)4.详细设计实现概要设计中定义的所有数据类型,对每个操作给出伪码算法。

二叉排序树的实验报告

二叉排序树的实验报告

二叉排序树的实验报告二叉排序树的实验报告引言:二叉排序树(Binary Search Tree,简称BST)是一种常用的数据结构,它将数据按照一定的规则组织起来,便于快速的查找、插入和删除操作。

本次实验旨在深入了解二叉排序树的原理和实现,并通过实验验证其性能和效果。

一、实验背景二叉排序树是一种二叉树,其中每个节点的值大于其左子树的所有节点的值,小于其右子树的所有节点的值。

这种特性使得在二叉排序树中进行查找操作时,可以通过比较节点的值来确定查找的方向,从而提高查找效率。

二、实验目的1. 理解二叉排序树的基本原理和性质;2. 掌握二叉排序树的构建、插入和删除操作;3. 验证二叉排序树在查找、插入和删除等操作中的性能和效果。

三、实验过程1. 构建二叉排序树首先,我们需要构建一个空的二叉排序树。

在构建过程中,我们可以选择一个节点作为根节点,并将其他节点插入到树中。

插入节点时,根据节点的值与当前节点的值进行比较,如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。

重复这个过程,直到所有节点都被插入到树中。

2. 插入节点在已有的二叉排序树中插入新的节点时,我们需要遵循一定的规则。

首先,从根节点开始,将新节点的值与当前节点的值进行比较。

如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。

如果新节点的值与当前节点的值相等,则不进行插入操作。

3. 删除节点在二叉排序树中删除节点时,我们需要考虑不同的情况。

如果要删除的节点是叶子节点,即没有左右子树,我们可以直接删除该节点。

如果要删除的节点只有一个子树,我们可以将子树连接到要删除节点的父节点上。

如果要删除的节点有两个子树,我们可以选择将其右子树中的最小节点或左子树中的最大节点替代该节点,并删除相应的替代节点。

四、实验结果通过对二叉排序树的构建、插入和删除操作的实验,我们得到了以下结果:1. 二叉排序树可以高效地进行查找操作。

数据结构实验-二叉排序树应用实验报告

数据结构实验-二叉排序树应用实验报告

实验报告实验课程:数据结构实验项目:实验四二叉排序树应用专业:计算机科学与技术班级:姓名:学号:指导教师:目录一、问题定义及需求分析(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); /* 若该节点小于当前节点,则在左子树中继续查找*/elsereturn 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为左孩子*/elsep->rchild = s; /* 插入s为右孩子*/return 1;}elsereturn 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的右子树*/elseq->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);/* 若待删除节点大于当前节点,则递归访问其左子树*/elsereturn 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个域名;第四步:回车,程序跳转至功能界面,根据提示输入想要执行的功能选项序号;第五步:回车后,针对各功能项有提示药查找、插入或者删除的节点;第六步:执行功能后,选择结束运行还是继续操作;第七步:若选择继续操作,则程序进入功能界面,可继续选择执行的功能;第八步:循环执行第四到七步;第九步:可在第六步选择退出程序;六、测试结果七、附录源代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#define ElemType chartypedef struct BiTNode{ElemType data[30]; //定义数据域类型为字符数组struct BiTNode *lchild, *rchild; //定义左右孩子节点指针}BiTNode, *BiTree;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; //p指向查找到的节点return 1;}else if (strcmp(key,T->data)<0)return SearchBST(T->lchild, key, T, p); // 在左子树中继续查找elsereturn SearchBST(T->rchild, key, T, p); // 在右子树中继续查找}int InsertBST(BiTree *T, char *key){BiTree p,s;if (!SearchBST(*T, key, NULL, &p)) // 查找不成功{s = (BiTNode*)malloc(sizeof(BiTNode));//s作为插入节点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为左孩子elsep->rchild = s; // 插入s为右孩子return 1;}elsereturn 0; // 树中已有关键字相同的结点,不再插入}int Search(BiTNode *N,char *key){ // 查找树中是否存在要插入的节点BiTNode *M;M=N;while(M!=NULL&&strcmp(M->data,key)!=0){ // 查找终止条件为树为空或者查找的节点数据与待查找的数据相同if(strcmp(M->data,key)<0)M=M->rchild; // 继续查找左子树elseM=M->lchild; // 继续查找右子树}if(!M)printf("查找失败!\n");elseprintf("查找成功!\n");}/* 从二叉排序树中删除结点p,并重接它的左或右子树。

数据结构实验报告二二叉树实验

数据结构实验报告二二叉树实验

实验报告课程名称:数据结构
第 1 页共4 页
五、实验总结(包括心得体会、问题回答及实验改进意见,可附页)
这次实验主要是建立二叉树,和二叉树的先序、中序、后续遍历算法。

通过这次实验,我巩固了二叉树这部分知识,从中体会理论知识的重要性。

在做实验之前,要充分的理解本次实验的理论依据,这样才能达到事半功倍的效果。

如果在没有真正理解实验原理之盲目的开始实验,只会浪费时间和精力。

例如进行二叉树的遍历的时候,要先理解各种遍历的特点。

先序遍历是先遍历根节点,再依次先序遍历左右子树。

中序遍历是先中序遍历左子树,再访问根节点,最后中序遍历右子树。

而后序遍历则是先依次后续遍历左右子树,再访问根节点。

掌握了这些,在实验中我们就可以融会贯通,举一反三。

其次要根据不光要懂得代码的原理,还要对题目有深刻的了解,要明白二叉树的画法,在纸上先进行自我演练,对照代码验证自己写的正确性。

第 3 页共4 页
第 4 页共4 页。

二叉排序树实验报告

二叉排序树实验报告

深圳大学实验报告
课程名称:数据结构实验与课程设计
实验项目名称:二叉排序树实验
学院:计算机与软件学院
专业:
指导教师:
报告人:学号:班级: 3班
实验时间: 2012-11-28 实验报告提交时间: 2012-12-5
教务部制
int main(int argc,char *argv[])
{
int t[32];
int i,j,Key;
int TestNum,SampleNum;
// freopen("cin.txt","r",stdin);
// freopen("cout.txt","w",stdout);
BiSortTree *BST=new BiSortTree;
cin>>TestNum;
for(i=0;i<TestNum;i++){
cin>>SampleNum;
for(j=0;j<SampleNum;j++) cin>>t[j];
BST->CreateBST(t,SampleNum);
cin>>Key;
BST->SearchBST(Key);
cout<<BST->BisSuccess<<" "<<BST->BisPos <<" "<<BST->BisCount<<endl;
}
return 0;
}
运行截图:
2、教师批改学生实验报告时间应在学生提交实验报告时间后10日内。

数据结构二叉排序树实验报告

数据结构二叉排序树实验报告

实验报告课程名:数据结构(C语言版)实验名:二叉排序树姓名:班级:学号:撰写时间:一实验目的与要求1.掌握二叉排序树上进行插入和删除的操作2.利用 C 语言实现该操作二实验内容•对于一个线形表, 利用不断插入的方法, 建立起一株二叉排序树•从该二叉排序树中删除一个叶子节点, 一个只有一个子树的非叶子节,一个有两个子树的非叶子节点。

三实验结果与分析#include<>#include<>删结点是叶子结点,直接删除if(p->left == NULL && p->right == NULL){删结点只有左子树else if(p->left && !(p->right)){p->left->parent=p->parent;删结点只有右孩子else if(p->right && !(p->left)){p->right->parent=p->parent;删除的结点既有左孩子,又有右孩子//该结点的后继结点肯定无左子树(参考上面查找后继结点函数)//删掉后继结点,后继结点的值代替该结点else{//找到要删除结点的后继q=searchSuccessor(p);temp=q->key;//删除后继结点deleteNode(root,q->key);p->key=temp;}return 1;}//创建一棵二叉查找树void create(PNode* root,KeyType *keyArray,int length) {int i;//逐个结点插入二叉树中for(i=0;i<length;i++)inseart(root,keyArray[i]);}int main(void){int i;PNode root=NULL;KeyType nodeArray[11]={15,6,18,3,7,17,20,2,4,13,9}; create(&root,nodeArray,11);for(i=0;i<2;i++)deleteNode(&root,nodeArray[i]);printf("%d\n",searchPredecessor(root)->key);printf("%d\n",searchSuccessor(root)->key);printf("%d\n",searchMin(root)->key);printf("%d\n",searchMax(root)->key);printf("%d\n",search(root,13)->key);return 0;}图1:二叉树排序实验结果。

数据结构二叉树的实验报告

数据结构二叉树的实验报告数据结构二叉树的实验报告一、引言数据结构是计算机科学中非常重要的一个领域,它研究如何组织和存储数据以便高效地访问和操作。

二叉树是数据结构中常见且重要的一种,它具有良好的灵活性和高效性,被广泛应用于各种领域。

本实验旨在通过实际操作和观察,深入了解二叉树的特性和应用。

二、实验目的1. 理解二叉树的基本概念和特性;2. 掌握二叉树的创建、遍历和查找等基本操作;3. 通过实验验证二叉树的性能和效果。

三、实验过程1. 二叉树的创建在实验中,我们首先需要创建一个二叉树。

通过输入一系列数据,我们可以按照特定的规则构建一棵二叉树。

例如,可以按照从小到大或从大到小的顺序将数据插入到二叉树中,以保证树的有序性。

2. 二叉树的遍历二叉树的遍历是指按照一定的次序访问二叉树中的所有节点。

常见的遍历方式有前序遍历、中序遍历和后序遍历。

前序遍历是先访问根节点,然后再依次遍历左子树和右子树;中序遍历是先遍历左子树,然后访问根节点,最后再遍历右子树;后序遍历是先遍历左子树,然后遍历右子树,最后访问根节点。

3. 二叉树的查找二叉树的查找是指在二叉树中寻找指定的节点。

常见的查找方式有深度优先搜索和广度优先搜索。

深度优先搜索是从根节点开始,沿着左子树一直向下搜索,直到找到目标节点或者到达叶子节点;广度优先搜索是从根节点开始,逐层遍历二叉树,直到找到目标节点或者遍历完所有节点。

四、实验结果通过实验,我们可以观察到二叉树的特性和性能。

在创建二叉树时,如果按照有序的方式插入数据,可以得到一棵平衡二叉树,其查找效率较高。

而如果按照无序的方式插入数据,可能得到一棵不平衡的二叉树,其查找效率较低。

在遍历二叉树时,不同的遍历方式会得到不同的结果。

前序遍历可以用于复制一棵二叉树,中序遍历可以用于对二叉树进行排序,后序遍历可以用于释放二叉树的内存。

在查找二叉树时,深度优先搜索和广度优先搜索各有优劣。

深度优先搜索在空间复杂度上较低,但可能会陷入死循环;广度优先搜索在时间复杂度上较低,但需要较大的空间开销。

二叉排序树实验报告

二叉排序树的实现一、实验内容与要求1)实现二叉排序树,包括生成、插入,删除;2)对二叉排序树进行先根、中根、和后根非递归遍历;3)每次对树的修改操作和遍历操作的显示结果都需要在屏幕上用树的形状表示出来。

二、实验方案1.选择链表的方式来构造节点,存储二叉排序树的节点。

//树的结构struct BSTNode{//定义左右孩子指针struct BSTNode *lchild,*rchild;//节点的关键字TElemType key;};int depth=0;//定义一个 struct BSTNode 类型的指针typedef BSTNode *Tree;2.对树的操作有如下方法:// 创建二叉排序树Tree CreatTree(Tree T);//二叉树的深度,返回一个int值为该树的深度int TreeDepth(Tree T)//树状输出二叉树,竖向输出void PrintTree(Tree T , int layer);//查找关键字,如果关键字存在则返回所在节点的父节点,如果关键字不存在则返回叶子所在的节点Status SearchBST(Tree T , TElemType key , Tree f,Tree &p);//向树中插入节点Status InsertBST(Tree &T , TElemType e);//删除节点Status Delete(Tree &T);//删除指定节点,调用Delete(Tree &T)方法Status DeleteData(Tree &T , TElemType key);//非递归先序遍历void x_print(Tree T);//非递归中序遍历Void z_print(Tree T );//非递归后序遍历void h_print(Tree T);3.对二叉排序树非递归先根、中根、后根遍历,采用栈来存储一次遍历过的节点的形式来辅助实现//自定义类型以 SElemType作为栈中指针返回的值的类型//也就是要返回一个节点的指针typedef Tree SElemType;//栈的结构struct Stack{//栈底指针SElemType *base;//栈顶指针SElemType *top;//栈的容量int stacksize;};4.栈的操作方法://创建一个空栈Status InitStack(Stack &S);//获取栈顶元素并删除栈中该位置的元素SElemType Pop(Stack &S,SElemType &elem)//获取栈顶元素返回栈顶元素不对栈做任何修改SElemType getTop(Stack S,SElemType &elem)//删除栈顶元素Status DeleteTop(Stack &S)//往栈中压入数据Status Push(Stack &S,SElemType elem)//判断栈是否为空Status IsEmpty(Stack S)三、代码实现#include <iostream>#include <math.h>using namespace std;//定义宏#define OK 1#define ERROR 0#define STACK_INIT_SIZE 10#define STACK_INCREMENT 2//定义宏分别为栈的初始容量和栈的增加容量#define STACK_INIT_SIZE 10#define STACK_INCREMENT 2typedef int TElemType;//树的结构struct BSTNode{//定义左右孩子指针struct BSTNode *lchild,*rchild;//节点的关键字TElemType key;};int depth=0;//定义一个 struct BSTNode 类型的指针typedef BSTNode *Tree;//自定义类型以 SElemType作为栈中指针返回的值的类型//也就是要返回一个节点的指针typedef Tree SElemType;//栈的结构struct Stack{//栈底指针SElemType *base;//栈顶指针SElemType *top;//栈的容量int stacksize;};//自定义类型typedef int Status;//创建一个空栈Status InitStack(Stack &S){//给栈指针分配空间S.base=(SElemType*)malloc(STACK_INIT_SIZE*sizeof(SElemType));//如果分配空间失败则退出if(!S.base)exit(OVERFLOW);//栈底、栈顶指针相等表示栈为空//S.base=S.top;//此句代码若以如上句格式则在执行时会出现内存非法访问的错误S.top=S.base;//初始化栈的容量S.stacksize=STACK_INIT_SIZE;return OK;}//获取栈顶元素并删除栈中该位置的元素SElemType Pop(Stack &S,SElemType &elem){if(S.top==S.base){cout<<"gai zhan yi jing wei kong "<<endl;return ERROR;}else{elem=*--S.top;}return elem;}//获取栈顶元素返回栈顶元素不对栈做任何修改SElemType getTop(Stack S,SElemType &elem){//如果为空栈则返回ERRORif(S.base==S.top){cout<<"gai zhan yi jing wei kong"<<endl;return ERROR;}//如果栈不为空则返回栈顶元素else{elem=*(S.top-1);}return elem;}//删除栈顶元素Status DeleteTop(Stack &S){//判断栈是否为空if(S.base==S.top){cout<<"gai zhan yi jing wei kong "<<endl;return ERROR;}//如果栈不为空则删除栈顶元素else{--S.top;}return OK;}//往栈中压入数据Status Push(Stack &S,SElemType elem){//如果栈的容量超过初始化容量则增加栈的容量if(S.top-S.base>=S.stacksize){S.base=(SElemType*)realloc(S.base,(S.stacksize+STACK_INCREMENT)*sizeof(SElemType));if(!S.base)exit(OVERFLOW);S.top=S.base+S.stacksize;S.stacksize+=STACK_INCREMENT;}//添加数据*S.top++=elem;return OK;}//判断栈是否为空Status IsEmpty(Stack S){if(S.base==S.top)return OK;elsereturn ERROR;}/////////////////////////////////////////////////////////////////// ///////////以下的代码主要是对树的操作///////////////////////////// /////////////////////////////////////////////////////////////////////创建空树Status InitTree(Tree &T){T=NULL;return OK;}//查找关键字//如果关键字存在则返回所在节点的父节点//如果关键字不存在则返回叶子所在的节点Status SearchBST(Tree T,TElemType key,Tree f,Tree &p) {if(!T){p=f;return ERROR;}else if(T->key==key){p=T;return OK;}else if(T->key>key)return SearchBST(T->lchild,key,T,p);else if(T->key<key)return SearchBST(T->rchild,key,T,p);}//向树中插入节点Status InsertBST(Tree &T,TElemType e){Tree p;if(!SearchBST(T,e,NULL,p)){Tree s=(Tree)malloc(sizeof(BSTNode));s->key=e;s->lchild=s->rchild=NULL;if(!p){T=s;}else if(p->key>e){p->lchild=s;}else if(p->key<e){p->rchild=s;}}elsereturn ERROR;}// 创建二叉排序树Tree CreatTree(Tree T){TElemType elem;cout<<"请输入数据,以0结束输入操作"<<endl;cin>>elem;while(elem!=0 && elem>0){int k= InsertBST(T,elem);if(k){cout<<"请输入数据,以0结束输入操作"<<endl;cin>>elem;}else{cout<<"插入错误或存在重复元素"<<endl;//异常退出return ERROR;}}return T;}//删除节点Status Delete(Tree &T){Tree p,q;if(T->lchild!=NULL && T->rchild!=NULL){p=T;q=T->lchild;T=q;while(q->rchild!=NULL){q=q->rchild;}q->rchild=p->rchild;free(p);return OK;}if(T->rchild==NULL && T->lchild!=NULL){p=T;T=T->lchild;free(p);return OK;}else if(T->lchild==NULL && T->rchild!=NULL) {p=T;T=T->rchild;free(p);return OK;}else if(T->rchild==NULL && T->lchild==NULL){T=NULL;free(T);return OK;}}//删除指定节点Status DeleteData(Tree &T,TElemType key){if(!T){cout<<"找不到要删除的元素,请重新选择!"<<endl;return ERROR;}if(T->key==key){Delete(T);}else if(T->key>key)DeleteData(T->lchild,key);else if(T->key<key)DeleteData(T->rchild,key);return OK;}//先序遍历void x_print(Tree T){//Tree f;Stack S;InitStack(S);if(T==NULL){cout<<"树为空"<<endl;}while(T!=NULL || !IsEmpty(S)){if(T!=NULL){cout<<T->key<<" ";Push(S,T);T=T->lchild;}else{Pop(S,T);T=T->rchild;}}}//z中序遍历void z_print(Tree T ){// Tree f;Stack S;InitStack(S);if(T==NULL){cout<<"树为空"<<endl;}while(T!=NULL || !IsEmpty(S)){if(T!=NULL){Push(S,T);T=T->lchild;}else{Pop(S,T);cout<<T->key<<" ";T=T->rchild;}}}//后序遍历void h_print(Tree T){Stack S;InitStack(S);Tree f=NULL;if(T==NULL){cout<<"树为空"<<endl;}while(T!=NULL || !IsEmpty(S)){while(T!=NULL){Push(S,T);T=T->lchild;}getTop(S,T);if(T->rchild==NULL || T->rchild==f){cout<<T->key<<" ";Pop(S,f);T=NULL;}else{T=T->rchild;}}}//二叉树的深度int TreeDepth(Tree T){int left,right,max;if(T!=NULL){left=TreeDepth(T->lchild);right=TreeDepth(T->rchild);max=left>right?left:right;return max+1;}else{return ERROR;}}//竖向输出//树状输出二叉树void PrintTree(Tree T,int layer){int k;if(T==NULL)return ;PrintTree(T->rchild,layer+1);for(k=0;k<layer;k++)cout<<" ";cout<<T->key<<"\n";PrintTree(T->lchild,layer+1);}void main(){int key;int h;Tree tree;InitTree(tree);tree=CreatTree(tree);h=TreeDepth(tree);cout<<"树状输出为:"<<endl;PrintTree(tree,h);if(!tree){exit(-1);}cout<<"\n\n---------------请输入你要选择的操作--------------------\n"<<endl;cout<<"a.删除二叉树中的元素 b.向二叉树中添加元素"<<endl;cout<<"c.先根遍历二叉树 d.中根遍历二叉树 "<<endl;cout<<"e.后根遍历二叉树 o.退出操作 "<<endl;cout<<"\n\n------------------------------------------------------\n"<<endl;//int key;char select;cin>>select;while(select!='o'){switch(select){case 'o':exit(0);break;case 'a':if(!tree){cout<<"树以为空,请重新选择操作!"<<endl;cin>>select;}else{cout<<"请输入要删除的元素"<<endl;cin>>key;DeleteData(tree,key);cout<<"树状输出为:"<<endl;PrintTree(tree,h);}break;case 'b':cout<<"请输入要插入的元素"<<endl;cin>>key;InsertBST(tree,key);cout<<"树状输出为:"<<endl;PrintTree(tree,h);break;case 'c':cout<<"先根遍历结果为:"<<endl;x_print(tree);cout<<endl;break;case 'd':cout<<"中根遍历结果为:"<<endl;z_print(tree);cout<<endl;break;case 'e':cout<<"后根遍历结果为:"<<endl;h_print(tree);cout<<endl;break;default:cout<<"输入错误"<<endl;exit(-1);break;}cout<<"---------------请输入你要选择的操作--------------------"<<endl;cout<<"a.删除二叉树中的元素 b.向二叉树中添加元素"<<endl;cout<<"c.先根遍历二叉树 d.中根遍历二叉树 "<<endl;cout<<"e.后根遍历二叉树 o.退出操作 "<<endl;cout<<"--------------------------------------------------------"<<endl;cin>>select;}}四、实验结果和数据处理输入数据同选择操作结果如上图所示操作现象:输入操作的时候如果输入的不是数值(比如字母)就会出现插入操作错误的提示,然后异常退出操作;或者当输入的关键字已在树中存在,也会提示“重复输入”然后异常退出(这点存在不足,应该修改为提示之后重新输入操作)删除现象:如果要删除的关键字不存在则会提示不存在该关键字然后重新输入,如果树为空则会提示树为空并重新选择操作遍历现象:如果树为空,则不会退出操作,而是提示“树为空”。

数据结构实验报告—二叉树

数据结构实验报告—二叉树数据结构实验报告—二叉树引言二叉树是一种常用的数据结构,它由节点和边构成,每个节点最多有两个子节点。

在本次实验中,我们将对二叉树的基本结构和基本操作进行实现和测试,并深入了解它的特性和应用。

实验目的1. 掌握二叉树的基本概念和特性2. 熟练掌握二叉树的基本操作,包括创建、遍历和查找等3. 了解二叉树在实际应用中的使用场景实验内容1. 二叉树的定义和存储结构:我们将首先学习二叉树的定义,并实现二叉树的存储结构,包括节点的定义和节点指针的表示方法。

2. 二叉树的创建和初始化:我们将实现二叉树的创建和初始化操作,以便后续操作和测试使用。

3. 二叉树的遍历:我们将实现二叉树的前序、中序和后序遍历算法,并测试其正确性和效率。

4. 二叉树的查找:我们将实现二叉树的查找操作,包括查找节点和查找最大值、最小值等。

5. 二叉树的应用:我们将探讨二叉树在实际应用中的使用场景,如哈夫曼编码、二叉搜索树等。

二叉树的定义和存储结构二叉树是一种特殊的树形结构,它的每个节点最多有两个子节点。

节点被表示为一个由数据和指向其左右子节点的指针组成的结构。

二叉树可以分为三类:满二叉树、完全二叉树和非完全二叉树。

二叉树可以用链式存储结构或顺序存储结构表示。

- 链式存储结构:采用节点定义和指针表示法,通过将节点起来形成一个树状结构来表示二叉树。

- 顺序存储结构:采用数组存储节点信息,通过计算节点在数组中的位置来进行访问和操作。

二叉树的创建和初始化二叉树的创建和初始化是二叉树操作中的基础部分。

我们可以通过手动输入或读取外部文件中的数据来创建二叉树。

对于链式存储结构,我们需要自定义节点和指针,并通过节点的方式来构建二叉树。

对于顺序存储结构,我们需要定义数组和索引,通过索引计算来定位节点的位置。

一般来说,初始化一个二叉树可以使用以下步骤:1. 创建树根节点,并赋初值。

2. 创建子节点,并到父节点。

3. 重复步骤2,直到创建完整个二叉树。

数据结构二叉树综合实验报告

数据结构二叉树综合实验报告数据结构二叉树综合实验报告1.引言在计算机科学中,二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点,分别称为左子节点和右子节点。

二叉树具有广泛的应用场景,如在搜索算法、图形处理和编译器设计中等。

本报告旨在介绍我们进行的二叉树综合实验,包括实验目的、实验过程中的具体步骤和实验结果分析等。

2.实验目的本实验的主要目的是通过设计和实现二叉树的基本操作,加深对二叉树的理解,并掌握二叉树的基本算法和应用。

具体的实验目标包括:- 熟悉二叉树的基本概念和性质;- 掌握二叉树的创建、插入和删除操作;- 实现二叉树的遍历算法,包括前序、中序和后序遍历;- 实现二叉树的搜索功能;- 进行基于二叉树的排序实验。

3.实验步骤3.1 二叉树的创建首先,我们需要创建一个空的二叉树。

通过定义二叉树的节点结构和指针,可以动态地分配内存空间用于创建节点,并建立节点之间的连接关系。

3.2 节点的插入在已有的二叉树中,我们可以向其中插入新的节点。

插入操作通常涉及到比较节点的键值大小,然后根据比较结果决定插入新节点的位置。

3.3 节点的删除除了插入节点,我们也可能需要从二叉树中删除节点。

删除操作通常需要考虑节点的子节点情况,例如,被删除的节点是否有左子节点、右子节点或者同时存在。

3.4 二叉树的遍历二叉树的遍历操作可以按照不同的顺序进行,包括前序(根-左-右)、中序(左-根-右)和后序(左-右-根)遍历。

在实验中,我们需要实现这三种遍历算法,并观察它们的输出结果。

3.5 二叉树的搜索在已有的二叉树中,我们可根据节点的键值进行搜索操作。

通过比较键值,我们可以判断在左子树或右子树中进行进一步的搜索,直至找到目标节点或确定目标节点不存在于二叉树中。

3.6 基于二叉树的排序二叉树可以作为一种排序算法的基础结构。

在实验中,我们可以通过节点的插入操作构建一个包含数据集的二叉树,并通过中序遍历获取有序的数据。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

实验报告实验课程:数据结构实验项目:实验四二叉排序树应用专业:计算机科学与技术班级:姓名:学号:指导教师:目录一、问题定义及需求分析(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); /* 若该节点小于当前节点,则在左子树中继续查找*/elsereturn 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为左孩子*/elsep->rchild = s; /* 插入s为右孩子*/return 1;}elsereturn 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的右子树*/elseq->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);/* 若待删除节点大于当前节点,则递归访问其左子树*/elsereturn 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个域名;第四步:回车,程序跳转至功能界面,根据提示输入想要执行的功能选项序号;第五步:回车后,针对各功能项有提示药查找、插入或者删除的节点;第六步:执行功能后,选择结束运行还是继续操作;第七步:若选择继续操作,则程序进入功能界面,可继续选择执行的功能;第八步:循环执行第四到七步;第九步:可在第六步选择退出程序;六、测试结果七、附录源代码:#include<stdio.h>#include<stdlib.h>#include<string.h>#define ElemType chartypedef struct BiTNode{ElemType data[30]; //定义数据域类型为字符数组struct BiTNode *lchild, *rchild; //定义左右孩子节点指针}BiTNode, *BiTree;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; //p指向查找到的节点return 1;}else if (strcmp(key,T->data)<0)return SearchBST(T->lchild, key, T, p); // 在左子树中继续查找elsereturn SearchBST(T->rchild, key, T, p); // 在右子树中继续查找}int InsertBST(BiTree *T, char *key){BiTree p,s;if (!SearchBST(*T, key, NULL, &p)) // 查找不成功{s = (BiTNode*)malloc(sizeof(BiTNode));//s作为插入节点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为左孩子elsep->rchild = s; // 插入s为右孩子return 1;}elsereturn 0; // 树中已有关键字相同的结点,不再插入}int Search(BiTNode *N,char *key){ // 查找树中是否存在要插入的节点BiTNode *M;M=N;while(M!=NULL&&strcmp(M->data,key)!=0){ // 查找终止条件为树为空或者查找的节点数据与待查找的数据相同if(strcmp(M->data,key)<0)M=M->rchild; // 继续查找左子树elseM=M->lchild; // 继续查找右子树}if(!M)printf("查找失败!\n");elseprintf("查找成功!\n");}/* 从二叉排序树中删除结点p,并重接它的左或右子树。

相关文档
最新文档