输入一组关键值,建立相应的二叉排序树,完成结点的查找和删除操作。
(1)可以实现删除根结点、叶子结点以及其它任意结点的功能。
(2)可随时显示操作的结果。#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#define NULL 0
typedef struct node //定义二叉排序树的结点
{
int key; //数据域
struct node *lchild, *rchild; //左、右孩子指针
}*bitree; //二叉排序树的结点结构bitree BSTInsert(bitree t,bitree s) //二叉排序树的插入的非递归算法
{
bitree p,q;
if(t==NULL) //二叉排序树为空的情况
{
t=s;
return(t);
}
p=t; //从根结点开始
while(p!=NULL)
{
q=p;
if(s->key==p->key) //查找到返回
return(t);
else //继续搜索
{
if(s->key<p->key) //搜索左子树
p=p->lchild;
else //搜索右子树
p=p->rchild;
}
}
if(s->key>q->key)
q->rchild=s;
else
q->lchild=s;
return(t);
}void BSTCreat(bitree &t) //建立一个有n个节点的二叉排序树算法
{
bitree s;
int key; //关键字
int i,n;
t=NULL;
cout<<"请输入结点数目:"<<endl;
cin>>n;
cout<<"请输入结点的值:"<<endl;
for(i=1;i<=n;i++)
{
cin>>key; //假定关键字为整型
s=(bitree)malloc(sizeof(bitree)); //生成一个新结点
s->lchild=NULL;
s->rchild=NULL;
s->key=key; //调用插入算法将s所指结点插入二叉排序树t中
t=BSTInsert(t,s);
}
}int BSTSearch(bitree t,int key) //二叉排序树查找的非递归算法
{
bitree p;
p=t;
while(p!=NULL && p->key!=key)
{
if(key<p->key)
p=p->lchild; //沿左子树查找
else
p=p->rchild; //沿右子树查找
}
if(p!=NULL)
return(1);
else
return(0);
}void BSTDelete(bitree t,int key) //二叉排序树中删除一个结点的算法
{
bitree p,q,s;
p=t;
q=NULL; //p指向待比较的结点,q指向p的前驱结点
while(p!=NULL && p->key!=key) //查找值域为key的结点
if(key<p->key)
{
q=p;
p=p->lchild;
}
else
{
q=p;
p=p->rchild;
}
if(p==NULL)
cout<<"该结点不存在"<<endl;
else if(p->lchild==NULL) //被删结点无左子树
{
if(q==NULL) t=p->rchild; //考虑p为根结点的情况
else if(q->lchild==p)
q->lchild=p->rchild; //p为双亲的左子树
else
q->rchild=p->rchild; //p为双亲的右子树
free(p); //释放p结点
}
else if(p->rchild==NULL) //被删除结点无右子树
{
if(q==NULL)
t=p->rchild; //考虑p为根结点的情况
else if(q->lchild==p)
q->lchild=p->rchild; //p为双亲的左子树
else
q->rchild=p->rchild; //p为双亲的右子树
free(p); //释放P结点
}
else //被删除结点同时有左子树和右子树
{ //查找被删除结点的左子树中的最右结点,即刚好小于key的结点,也即是p的直接前驱
s=p->lchild;
while(s->rchild!=NULL) //寻找p的直接前驱s
s=s->rchild;
s->rchild=p->rchild; //被删除结点的右子树作为直接前驱s的右子树
//被删除结点的左子树根代替被删结点
if(q==NULL) //被删结点是根结点
t=p->lchild;
else if(q->lchild==p) //p为其双亲结点左子树
q->lchild=p->lchild;
else //p为双亲的右子树
q->rchild=p->lchild;
free(p);
}
}void BSTPrint(bitree t)
{
if(t!=NULL)
{
BSTPrint(t->lchild);
printf("%d\t",t->key);
BSTPrint(t->rchild);
}
}void main()
{
int k;
bitree p,s1;
int key1;
cout<<"建立二叉排序树:"<<endl;
p=NULL;
s1=NULL;
BSTCreat(p);
cout<<"请输入需要查找关键字:"<<endl;
cin>>key1;
k=BSTSearch(p,key1);
if(!k)
cout<<"该结点不存在"<<endl;
else
cout<<"该结点存在,已找到"<<endl;
cout<<"请输入要删除的结点关键字的值"<<endl;
cin>>key1;
BSTDelete(p,key1);
cout<<"删除结点后的二叉排序树的中序遍历为:"<<endl;
BSTPrint(p);}程序编译和连接时均未出错,但运行生成的exe做删除结点操作时出错。请各位大虾指点!
(1)可以实现删除根结点、叶子结点以及其它任意结点的功能。
(2)可随时显示操作的结果。#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#define NULL 0
typedef struct node //定义二叉排序树的结点
{
int key; //数据域
struct node *lchild, *rchild; //左、右孩子指针
}*bitree; //二叉排序树的结点结构bitree BSTInsert(bitree t,bitree s) //二叉排序树的插入的非递归算法
{
bitree p,q;
if(t==NULL) //二叉排序树为空的情况
{
t=s;
return(t);
}
p=t; //从根结点开始
while(p!=NULL)
{
q=p;
if(s->key==p->key) //查找到返回
return(t);
else //继续搜索
{
if(s->key<p->key) //搜索左子树
p=p->lchild;
else //搜索右子树
p=p->rchild;
}
}
if(s->key>q->key)
q->rchild=s;
else
q->lchild=s;
return(t);
}void BSTCreat(bitree &t) //建立一个有n个节点的二叉排序树算法
{
bitree s;
int key; //关键字
int i,n;
t=NULL;
cout<<"请输入结点数目:"<<endl;
cin>>n;
cout<<"请输入结点的值:"<<endl;
for(i=1;i<=n;i++)
{
cin>>key; //假定关键字为整型
s=(bitree)malloc(sizeof(bitree)); //生成一个新结点
s->lchild=NULL;
s->rchild=NULL;
s->key=key; //调用插入算法将s所指结点插入二叉排序树t中
t=BSTInsert(t,s);
}
}int BSTSearch(bitree t,int key) //二叉排序树查找的非递归算法
{
bitree p;
p=t;
while(p!=NULL && p->key!=key)
{
if(key<p->key)
p=p->lchild; //沿左子树查找
else
p=p->rchild; //沿右子树查找
}
if(p!=NULL)
return(1);
else
return(0);
}void BSTDelete(bitree t,int key) //二叉排序树中删除一个结点的算法
{
bitree p,q,s;
p=t;
q=NULL; //p指向待比较的结点,q指向p的前驱结点
while(p!=NULL && p->key!=key) //查找值域为key的结点
if(key<p->key)
{
q=p;
p=p->lchild;
}
else
{
q=p;
p=p->rchild;
}
if(p==NULL)
cout<<"该结点不存在"<<endl;
else if(p->lchild==NULL) //被删结点无左子树
{
if(q==NULL) t=p->rchild; //考虑p为根结点的情况
else if(q->lchild==p)
q->lchild=p->rchild; //p为双亲的左子树
else
q->rchild=p->rchild; //p为双亲的右子树
free(p); //释放p结点
}
else if(p->rchild==NULL) //被删除结点无右子树
{
if(q==NULL)
t=p->rchild; //考虑p为根结点的情况
else if(q->lchild==p)
q->lchild=p->rchild; //p为双亲的左子树
else
q->rchild=p->rchild; //p为双亲的右子树
free(p); //释放P结点
}
else //被删除结点同时有左子树和右子树
{ //查找被删除结点的左子树中的最右结点,即刚好小于key的结点,也即是p的直接前驱
s=p->lchild;
while(s->rchild!=NULL) //寻找p的直接前驱s
s=s->rchild;
s->rchild=p->rchild; //被删除结点的右子树作为直接前驱s的右子树
//被删除结点的左子树根代替被删结点
if(q==NULL) //被删结点是根结点
t=p->lchild;
else if(q->lchild==p) //p为其双亲结点左子树
q->lchild=p->lchild;
else //p为双亲的右子树
q->rchild=p->lchild;
free(p);
}
}void BSTPrint(bitree t)
{
if(t!=NULL)
{
BSTPrint(t->lchild);
printf("%d\t",t->key);
BSTPrint(t->rchild);
}
}void main()
{
int k;
bitree p,s1;
int key1;
cout<<"建立二叉排序树:"<<endl;
p=NULL;
s1=NULL;
BSTCreat(p);
cout<<"请输入需要查找关键字:"<<endl;
cin>>key1;
k=BSTSearch(p,key1);
if(!k)
cout<<"该结点不存在"<<endl;
else
cout<<"该结点存在,已找到"<<endl;
cout<<"请输入要删除的结点关键字的值"<<endl;
cin>>key1;
BSTDelete(p,key1);
cout<<"删除结点后的二叉排序树的中序遍历为:"<<endl;
BSTPrint(p);}程序编译和连接时均未出错,但运行生成的exe做删除结点操作时出错。请各位大虾指点!
解决方案 »
- 怎样用三层循环ijk表示顺序数123456789?
- 我想把没用的注释掉的代码删掉
- VC代码实现退出系统
- CMainFrame里的滚动条如何滚动视图
- 如何include服务器上的头文件?
- 如何用VC获取网中的有用信息
- 新手:如何产看GetLastError得到的错误代码的内容是什么?
- 再问:如何能最最简单的方法显示一张图片,能看见图片就成。
- 服务器端程序使用完全端口模型或重叠I/O模型效果会更好一些,通信事件的管理也方便。那位大侠给详细解释一下?
- 拜托各位大神看看,我的MFC程序 在子对话框中调用SetDlgItem()后没有在EDIT CONTROL 控件上显示出内容
- 请教高手,怎么在改变菜单的焦点?
- 100分求解,不够在加,如何将真彩32色图片二值化,请高手指点
1. s=(bitree)malloc(sizeof(bitree)); //生成一个新结点
这里的sizeof(bitree)取的是指针长度4,要换成sizeof(node);
2.free(p);之后要p=NULL,否则成了野指针
3.void BSTDelete(bitree t,int key);原型应为void BSTDelete(bitree *t,int key);
也就是传二级指针,才能准确回传指针值
修改过的代码如下:
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#define NULL 0
typedef struct node //定义二叉排序树的结点
{
int key; //数据域
struct node *lchild, *rchild; //左、右孩子指针
}*bitree; //二叉排序树的结点结构bitree BSTInsert(bitree t,bitree s) //二叉排序树的插入的非递归算法
{
bitree p,q;
if(t==NULL) //二叉排序树为空的情况
{
t=s;
return(t);
}
p=t; //从根结点开始
while(p!=NULL)
{
q=p;
if(s->key==p->key) //查找到返回
return(t);
else //继续搜索
{
if(s->key<p->key) //搜索左子树
p=p->lchild;
else //搜索右子树
p=p->rchild;
}
}
if(s->key>q->key)
q->rchild=s;
else
q->lchild=s;
return(t);
}void BSTCreat(bitree &t) //建立一个有n个节点的二叉排序树算法
{
bitree s;
int key; //关键字
int i,n;
t=NULL;
cout<<"请输入结点数目:"<<endl;
cin>>n;
cout<<"请输入结点的值:"<<endl;
for(i=1;i<=n;i++)
{
cin>>key; //假定关键字为整型
s=(bitree)malloc(sizeof(node)); //生成一个新结点
s->lchild=NULL;
s->rchild=NULL;
s->key=key; //调用插入算法将s所指结点插入二叉排序树t中
t=BSTInsert(t,s);
}
}int BSTSearch(bitree t,int key) //二叉排序树查找的非递归算法
{
bitree p;
p=t;
while(p!=NULL && p->key!=key)
{
if(key<p->key)
p=p->lchild; //沿左子树查找
else
p=p->rchild; //沿右子树查找
}
if(p!=NULL)
return(1);
else
return(0);
}void BSTDelete(bitree *t,int key) //二叉排序树中删除一个结点的算法
{
bitree p,q,s;
p=*t;
q=NULL; //p指向待比较的结点,q指向p的前驱结点
while(p!=NULL && p->key!=key) //查找值域为key的结点
{
if(key<p->key)
{
q=p;
p=p->lchild;
}
else
{
q=p;
p=p->rchild;
}
}
if(p==NULL)
cout<<"该结点不存在"<<endl;
else if(p->lchild==NULL) //被删结点无左子树
{
if(q==NULL) *t=p->rchild; //考虑p为根结点的情况
else if(q->lchild==p)
q->lchild=p->rchild; //p为双亲的左子树
else
q->rchild=p->rchild; //p为双亲的右子树
free(p); //释放p结点
p = NULL;
}
else if(p->rchild==NULL) //被删除结点无右子树
{
if(q==NULL)
*t=p->rchild; //考虑p为根结点的情况
else if(q->lchild==p)
q->lchild=p->rchild; //p为双亲的左子树
else
q->rchild=p->rchild; //p为双亲的右子树
free(p); //释放P结点
p = NULL;
}
else //被删除结点同时有左子树和右子树
{ //查找被删除结点的左子树中的最右结点,即刚好小于key的结点,也即是p的直接前驱
s=p->lchild;
while(s->rchild!=NULL) //寻找p的直接前驱s
s=s->rchild;
s->rchild=p->rchild; //被删除结点的右子树作为直接前驱s的右子树
//被删除结点的左子树根代替被删结点
if(q==NULL) //被删结点是根结点
*t=p->lchild;
else if(q->lchild==p) //p为其双亲结点左子树
q->lchild=p->lchild;
else //p为双亲的右子树
q->rchild=p->lchild;
free(p);
p = NULL;
}
}void BSTPrint(bitree t)
{
if(t!=NULL)
{
BSTPrint(t->lchild);
printf("%d\t",t->key);
BSTPrint(t->rchild);
}
}void main()
{
int k;
bitree p,s1;
int key1;
cout<<"建立二叉排序树:"<<endl;
p=NULL;
s1=NULL;
BSTCreat(p);
cout<<"请输入需要查找关键字:"<<endl;
cin>>key1;
k=BSTSearch(p,key1);
if(!k)
cout<<"该结点不存在"<<endl;
else
cout<<"该结点存在,已找到"<<endl;
cout<<"请输入要删除的结点关键字的值"<<endl;
cin>>key1;
BSTDelete(&p,key1);
cout<<"删除结点后的二叉排序树的中序遍历为:"<<endl;
BSTPrint(p);
}