实验报告 实验三 二叉排序树的建立和查找
数据结构实验报告3-二叉树

北京物资学院信息学院实验报告课程名数据结构(C++)实验实验名称二叉树算法的实现实验日期年月日实验报告日期年月日姓名______ ___ 班级_____ _______ 学号___一、实验目的1.掌握二叉树的存储的结构;2. 掌握建立二叉树的算法;3. 掌握对二叉树的遍历算法;4. 掌握二叉搜索树的算法;5. 掌握建立哈夫曼树和哈夫曼编码的算法;二、实验内容基本部分1. 采用广义表形式建立二叉树(参考图5-11(a)和/或图5-13(a));2. 对已建立的二叉树,进行先、中、后序和按层遍历;3. 用广义表形式输出二叉树;4. 【习题5-3】1, 2 (2题选作)【提示:参考递归遍历算法】;特殊二叉树部分1.用插入算法建立一棵二叉搜索树,原始数据为:{30,50,20,40,25,70,54,23,80,92},并中序遍历该树、查找其中的元素;2. 构造一棵叶子结点权值分别为3,5,6,7,9,13,21的哈夫曼树;3. 对2题进行哈夫曼编码。
三、实验地点与环境3.1 实验地点(南实验楼教室)3.2实验环境(所用语言环境)四、实验步骤1.2.3.…五、实验结果与分析5.1 实验结果(原始数据,预期结果和运行结果)序号算法名称(函数名) 所在头文件名原始数据与与功能主函数所在文件名运行结果*1 函数名:功能:头文件:CPP文件:原始数据:运行结果:23* 如果不能按“原始数据”、“运行结果”列出数据则不列,必要时在“分析”部分说明5.2 分析(选择部分算法分析,包括函数参数说明、调试中所遇到的问题和解决方法、中间结果等,必要时给出函数和主函数的关键段落。
所选算法应是:重要的算法、有编程特点的算法等)六、小结(收获与心得)。
二叉树的建立及其遍历实验报告

数据结构实验报告———二叉树的建立及其遍历一、实验目的1、了解二叉树的建立的方法及其遍历的顺序,熟悉二叉树的三种遍历2、检验输入的数据是否可以构成一颗二叉树二、实验的描述和算法1、实验描述二叉树的建立首先要建立一个二叉链表的结构体,包含根节点和左右子树。
因为耳熟的每一个左右子树又是一颗二叉树,所以可以用递归的方法来建立其左右子树。
二叉树的遍历是一种把二叉树的每一个节点访问完并输出的过程,遍历时根结点与左右孩子的输出顺序构成了不同的遍历方法,这个过程需要按照不同的遍历的方法,先输出根结点还是先输出左右孩子,可以用选择语句实现。
2、算法#include <stdio.h>#include <stdlib.h>#define OVERFLOW 0#define OK 1#define ERROR 0typedef struct BiTNode {char data;struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;BiTree CreateBiTree(BiTree T){scanf("%c",&e);if(e==' ') T=NULL;else {if(!(T=(BiTNode *)malloc(sizeof(BiTNode))))exit(OVERFLOW);T->data=e;T->lchild=CreateBiTree(T->lchild);T->rchild=CreateBiTree(T->rchild);}return T; }/************************前序遍历***********************/ char PreOrderTraverse(BiTree T,char (* Visit)(char e)){if(T){if(Visit(T->data))if(PreOrderTraverse(T->lchild,Visit))if(PreOrderTraverse(T->rchild,Visit)) return OK;return ERROR;}else return OK;}char Visit(char e){printf("%5c",e);return OK;}main(){printf("请输入一颗二叉树,按回车结束:\n");T=CreateBiTree(T);printf("先序遍历的结果:");PreOrderTraverse(T,Visit);}三、调试分析在调这个程序是并没有遇到很大的困难,就是在输入一颗二叉树时,遇到了一点麻烦。
二叉排序树的实验报告

二叉排序树的实验报告二叉排序树的实验报告引言:二叉排序树(Binary Search Tree,简称BST)是一种常用的数据结构,它将数据按照一定的规则组织起来,便于快速的查找、插入和删除操作。
本次实验旨在深入了解二叉排序树的原理和实现,并通过实验验证其性能和效果。
一、实验背景二叉排序树是一种二叉树,其中每个节点的值大于其左子树的所有节点的值,小于其右子树的所有节点的值。
这种特性使得在二叉排序树中进行查找操作时,可以通过比较节点的值来确定查找的方向,从而提高查找效率。
二、实验目的1. 理解二叉排序树的基本原理和性质;2. 掌握二叉排序树的构建、插入和删除操作;3. 验证二叉排序树在查找、插入和删除等操作中的性能和效果。
三、实验过程1. 构建二叉排序树首先,我们需要构建一个空的二叉排序树。
在构建过程中,我们可以选择一个节点作为根节点,并将其他节点插入到树中。
插入节点时,根据节点的值与当前节点的值进行比较,如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。
重复这个过程,直到所有节点都被插入到树中。
2. 插入节点在已有的二叉排序树中插入新的节点时,我们需要遵循一定的规则。
首先,从根节点开始,将新节点的值与当前节点的值进行比较。
如果小于当前节点的值,则将其插入到当前节点的左子树中;如果大于当前节点的值,则将其插入到当前节点的右子树中。
如果新节点的值与当前节点的值相等,则不进行插入操作。
3. 删除节点在二叉排序树中删除节点时,我们需要考虑不同的情况。
如果要删除的节点是叶子节点,即没有左右子树,我们可以直接删除该节点。
如果要删除的节点只有一个子树,我们可以将子树连接到要删除节点的父节点上。
如果要删除的节点有两个子树,我们可以选择将其右子树中的最小节点或左子树中的最大节点替代该节点,并删除相应的替代节点。
四、实验结果通过对二叉排序树的构建、插入和删除操作的实验,我们得到了以下结果:1. 二叉排序树可以高效地进行查找操作。
二叉树的建立和遍历的实验报告doc

二叉树的建立和遍历的实验报告篇一:二叉树的建立及遍历实验报告实验三:二叉树的建立及遍历【实验目的】(1)掌握利用先序序列建立二叉树的二叉链表的过程。
(2)掌握二叉树的先序、中序和后序遍历算法。
【实验内容】1. 编写程序,实现二叉树的建立,并实现先序、中序和后序遍历。
如:输入先序序列abc###de###,则建立如下图所示的二叉树。
并显示其先序序列为:abcde中序序列为:cbaed后序序列为:cbeda【实验步骤】1.打开VC++。
2.建立工程:点File->New,选Project标签,在列表中选Win32 Console Application,再在右边的框里为工程起好名字,选好路径,点OK->finish。
至此工程建立完毕。
3.创建源文件或头文件:点File->New,选File标签,在列表里选C++ Source File。
给文件起好名字,选好路径,点OK。
至此一个源文件就被添加到了你刚创建的工程之中。
4.写好代码5.编译->链接->调试#include#include#define OK 1#define OVERFLOW -2typedef int Status;typedef char TElemType;typedef struct BiTNode{TElemType data;struct BiTNode *lchild, *rchild;}BiTNode,*BiTree;Status CreateBiTree(BiTree &T){TElemType ch;scanf("%c",&ch);if (ch=='#')T= NULL;else{if (!(T = (BiTNode *)malloc(sizeof(BiTNode))))return OVERFLOW;T->data = ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); }return OK;} // CreateBiTreevoid PreOrder(BiTree T) {if(T){printf("%c",T->data); PreOrder(T->lchild); PreOrder(T->rchild);}}void InOrder(BiTree T) {if(T){InOrder(T->lchild);printf("%c",T->data);InOrder(T->rchild);}}void PostOrder(BiTree T){if(T){PostOrder(T->lchild); PostOrder(T->rchild);printf("%c",T->data);}}void main(){BiTree T;CreateBiTree(T);printf("\n先序遍历序列:"); PreOrder(T);printf("\n中序遍历序列:"); InOrder(T);printf("\n后序遍历序列:"); PostOrder(T);}【实验心得】这次实验主要是通过先序序列建立二叉树,和二叉树的先序、中序、后续遍历算法。
数据结构二叉排序树实验报告

实验报告课程名:数据结构(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.选择链表的方式来构造节点,存储二叉排序树的节点。
//树的结构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;}}四、实验结果和数据处理输入数据同选择操作结果如上图所示操作现象:输入操作的时候如果输入的不是数值(比如字母)就会出现插入操作错误的提示,然后异常退出操作;或者当输入的关键字已在树中存在,也会提示“重复输入”然后异常退出(这点存在不足,应该修改为提示之后重新输入操作)删除现象:如果要删除的关键字不存在则会提示不存在该关键字然后重新输入,如果树为空则会提示树为空并重新选择操作遍历现象:如果树为空,则不会退出操作,而是提示“树为空”。
数据结构实验3:二叉树的操作

TextFile中。
(4) P:打印代码文件(Print)。
将文件CodeFile以紧凑格式显示在终端上,每行50个代码。
同时将此字符形式的编码文件写入文件CodePrin中。
(5) T:打印哈夫曼树(Tree printing)。
将已在内存中的哈夫曼树以直观的方式显示在终端上,同时将此字符形式的哈夫曼树写入文件TreePrint中。
3) 实现提示:(1) 文件CodeFile的基类型可以设为字节型。
(2) 用户界面可以设计为“菜单”方式:显示上述功能符号,再加上“Q”,表示退出运行Quit。
请用户键入一个选择功能符。
此功能执行完毕后再显示此菜单,直至某次用户选择了“E”为止。
(3) 在程序的一次执行过程中,第一次执行I、D或C命令之后,哈夫曼树已经在内存了,不必再读入。
每次执行中不一定执行I命令,因为文件hfmTree可能早已建好。
三、实验过程与实验结果实验3-01:以二叉链表为存储结构,实现二叉树的创建、遍历数据结构定义:typedef struct BiTNode{char data;BiTNode *lchild, *rchild;}BiTNode;typedef BiTNode *BiTree;算法设计思路简介:本实验需要实现以下操作:二叉树的初始化、前中后序遍历等基本操作1.利用递归实现前后序遍历,思路简洁,仅需要调整递归体的执行顺序即可实现。
2.利用非递归实现中序遍历,需要利用栈操作,按照中序遍历规则将节点依次入栈后出栈实现。
算法描述:图1 中序遍历(非递归)实现算法的实现和测试结果(参考OJ)实验3-02:编写算法交换二叉树中所有结点的左、右子树数据结构定义:typedef struct BiTNode{char data;BiTNode *lchild, *rchild;}BiTNode;typedef BiTNode *BiTree;算法设计思路简介:本实验需要实现以下操作:二叉树的初始化、前中后序遍历等基本操作1.利用递归实现前后序遍历,思路简洁,仅需要调整递归体的执行顺序即可实现。
数据结构实验三——二叉树基本操作及运算实验报告

《数据结构与数据库》实验报告实验题目二叉树的基本操作及运算一、需要分析问题描述:实现二叉树(包括二叉排序树)的建立,并实现先序、中序、后序和按层次遍历,计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目,以及二叉树常用运算。
问题分析:二叉树树型结构是一类重要的非线性数据结构,对它的熟练掌握是学习数据结构的基本要求。
由于二叉树的定义本身就是一种递归定义,所以二叉树的一些基本操作也可采用递归调用的方法。
处理本问题,我觉得应该:1、建立二叉树;2、通过递归方法来遍历(先序、中序和后序)二叉树;3、通过队列应用来实现对二叉树的层次遍历;4、借用递归方法对二叉树进行一些基本操作,如:求叶子数、树的深度宽度等;5、运用广义表对二叉树进行广义表形式的打印。
算法规定:输入形式:为了方便操作,规定二叉树的元素类型都为字符型,允许各种字符类型的输入,没有元素的结点以空格输入表示,并且本实验是以先序顺序输入的。
输出形式:通过先序、中序和后序遍历的方法对树的各字符型元素进行遍历打印,再以广义表形式进行打印。
对二叉树的一些运算结果以整型输出。
程序功能:实现对二叉树的先序、中序和后序遍历,层次遍历。
计算叶子结点数、树的深度、树的宽度,求树的非空子孙结点个数、度为2的结点数目、度为2的结点数目。
对二叉树的某个元素进行查找,对二叉树的某个结点进行删除。
测试数据:输入一:ABC□□DE□G□□F□□□(以□表示空格),查找5,删除E预测结果:先序遍历ABCDEGF中序遍历CBEGDFA后序遍历CGEFDBA层次遍历ABCDEFG广义表打印A(B(C,D(E(,G),F)))叶子数3 深度5 宽度2 非空子孙数6 度为2的数目2 度为1的数目2查找5,成功,查找的元素为E删除E后,以广义表形式打印A(B(C,D(,F)))输入二:ABD□□EH□□□CF□G□□□(以□表示空格),查找10,删除B预测结果:先序遍历ABDEHCFG中序遍历DBHEAGFC后序遍历DHEBGFCA层次遍历ABCDEFHG广义表打印A(B(D,E(H)),C(F(,G)))叶子数3 深度4 宽度3 非空子孙数7 度为2的数目2 度为1的数目3查找10,失败。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验三二叉排序树的建立和查找
一、实验目的
1.掌握二叉排序树的建立算法
2.掌握二叉排序树查找算法。
二、实验环境
操作系统和C语言系统
三、预习要求
复习二叉排序树的生成及查找算法,编写完整的程序。
四、实验内容
实现二叉排序树上的查找算法。
具体实现要求:用二叉链表做存储结构,输入键值序列,建立一棵二叉排序树并在二叉排序树上实现查找算法。
五、参考算法
#include <stdio.h>
#include <stdlib.h>
typedef int InfoType;
typedef int KeyType; /*假定关键字类型为整数*/
typedef struct node /*结点类型*/
{
KeyType key; /*关键字项*/
InfoType otherinfo; /*其它数据域,InfoType视应用情况而定,下面不处理它*/
struct node *lchild,*rchild; /*左右孩子指针*/
}BSTNode;
typedef BSTNode *BSTree; /*BSTree是二叉排序树的类型*/
BSTNode *SearchBST(BSTree T,KeyType key)
{ /*在二叉排序树T上查找关键字为key的结点,成功时返回该结点位置,否则返回NULL*/
if(T==NULL||key==T->key) /*递归的终结条件*/
return T; /*若T为空,查找失败;否则成功,返回找到的结点位置*/
if(key<T->key)
return SearchBST(T->lchild,key);
else
return SearchBST(T->rchild,key); /*继续在右子树中查找*/
}
void InsertBST(BSTree *T,int key)
{ /*插入一个值为key的节点到二叉排序树中*/
BSTNode *p,*q;
if((*T)==NULL)
{ /*树为空树*/
(*T)=(BSTree)malloc(sizeof(BSTNode));
(*T)->key=key;
(*T)->lchild=(*T)->rchild=NULL;
}
else
{
p=(*T);
while(p)
{
q=p;
if(p->key>key)
p=q->lchild;
else if(p->key<key)
p=q->rchild;
else
{
printf("\n 该二叉排序树中含有关键字为%d的节点!\n",key);
return;
}
}
p=(BSTree)malloc(sizeof(BSTNode));
p->key=key;
p->lchild=p->rchild=NULL;
if(q->key>key)
q->lchild=p;
else
q->rchild=p;
}
}
BSTree CreateBST(void)
{ /*输入一个结点序列,建立一棵二叉排序树,将根结点指针返回*/
BSTree T=NULL; /*初始时T为空树*/
KeyType key;
scanf("%d",&key); /*读入一个关键字*/
while(key)
{ /*假设key=0是输入结束标志*/ InsertBST(&T,key); /*将key插入二叉排序树T*/
scanf("%d",&key); /*读入下一关键字*/
}
return T; /*返回建立的二叉排序树的根指针*/ }
void ListBinTree(BSTree T) /*用广义表示二叉树*/
{
if(T!=NULL)
{
printf("%d",T->key);
if(T->lchild!=NULL||T->rchild!=NULL)
{
printf("(");
ListBinTree(T->lchild);
if(T->rchild!=NULL)
printf(",");
ListBinTree(T->rchild);
printf(")");
}
}
}
void main()
{
BSTNode *SearchBST(BSTree T,KeyType key);
void InsertBST(BSTree *Tptr,KeyType key);
BSTree CreateBST();
void ListBinTree(BSTree T);
BSTree T;
BSTNode *p;
int key;
printf("请输入关键字(输入0为结束标志):\n");
T=CreateBST();
ListBinTree(T);
printf("\n");
printf("请输入欲查找关键字:");
scanf("%d",&key);
p=SearchBST(T,key);
if(p==NULL)
printf("没有找到%d!\n",key);
else
printf("找到%d!\n",key);
ListBinTree(p);
printf("\n");
}
实验中出现的问题及对问题的解决方案
输入数据时,总是不能得到结果,原因是在建立二叉树函数定义中,是对指针的值进行了修改。
解决方案:用指向指针的指针。
其次,实验中经常会出现前后字符不一致的情况,主要原因是自己在编程时比较马虎,遇到比较长的程序,就容易出错。
可以通过评审多加练习,仔细认真检查自己是否出现错误。
同时在类似(*T)->key=key的语句中,括号没加,程序无法运行。
解决方案同上一条。
六、思考题
请思考采用其他存储结构实现的二叉排序树建立算法。
用下列程序代替源程序中的相应部分。
void InsertBST(BSTree *Tptr,KeyType key)
{
BSTBode *f,*p=*Tptr;
while(p)
{
if(p->key==key)
return;
f=p;
p=(key<p->key)?p->lchild:p->rchild;
}
p=(BSTNode *)malloc(sizeof(BSTNode));
p->key=key;
p->lchild=p->rchild=NULL;
if(*Tptr==NULL)
*Tptr=pp;
else
if(key<f->key)
f->lchild=p;
else
f->rchild=p;
}
BSTree CreateBST(void)
{
BSTree T=NULL;
KeyType key;
scanf("%d",&key);
while(key)
{
InsertBST(&T,key);
scanf("%d",&key);
}
return T;
}
七、实验总结
在开始编程时,不知道从何入手,自己在上课听讲了,也听懂了。
在编程是想自己独立完成,但看到要求之后突然感觉很迷茫,不得已借鉴了老师提供的代码。
其中有诸多原因,首先自己在编程经验上严重欠缺,这使得自己在接到一道题时无从下手,另外对二叉排序树的理解不够深入,所以编程都是建立在对其算法结构有深入理解的基础上的。
而且听懂不意味着理解,只有在自己亲自编程的时间过程中,才能逐渐加深理解。
自己C语言的底子不够厚实,今后要加强C语言知识的理论学习,系统地掌握C语言。
这样才能给实践提供良好的理论基础。