二叉排序树的基本应用
1.问题描述
[题目描述]
编写算法实现对依次输入的关键字序列建立二叉排序树,并能实现二叉排序树的查找、插入和删除运算。
2.需求分析
typedef struct BSTNode
{
int data; //每个结点的数据域
struct BSTNode *lchild, *rchild;//左右孩子指针
}BSTnode, *BSTree;
3.算法设计
1. Tree_Search(BSTree T, int key)//在根指针T所指二叉排序数中递归查找某关键字等于key的数据域
2. Tree_Insert(BSTree T, int key)//二叉排序树插入操作
3. Tree_Delete(BSTree T, int key)//删除指定的节点
4. Create() //创建二叉排序树
5. inorder(BSTree T) //中序遍历
6. menu()//菜单
4.调试分析
结构体存储结点,使用指针操作二叉排序树,更加灵活方便。对以构造好的二叉排序树进行遍历,要升序遍历采用中序遍历二叉树的方法,先遍历根结点,再遍历左子树,最后遍历右子树。
5.实验结果
1.二叉排序树的创建
2.二叉排序树的插入
3.二叉排序树的删除
4.二叉排序树的查找
5.二叉排序树的中序遍历
#include <iostream>
#include<stdlib.h>
using namespace std;
typedef struct BSTNode
{
int data; //每个结点的数据域
struct BSTNode *lchild, *rchild;//左右孩子指针
}BSTnode, *BSTree;
bool Tree_Search(BSTree T, int key)//在根指针T所指二叉排序数中递归查找某关键字等于key的数据域
{
BSTree p = T;
while(p)
{
if(key == p->data)
return true; //查找结束
else
p = (key < p -> data)?(p->lchild):(p->rchild);//在左右子树中继续查找
}
return false;
}
BSTree Tree_Insert(BSTree T, int key)//二叉排序树插入操作
{
BSTree p = T;
BSTree f,s;
while(p != NULL)
{
f= p;
if(key == p->data)
{
cout<<"要插入的节点已存在,不必再插入!"<<endl;
return T;
}
p = (key > p->data)? p->rchild:p->lchild;
}
s = new BSTnode;//生成新结点*s
s -> data = key;//新结点*s的数据域置为key
s -> lchild = s -> rchild = NULL;//把新结点*s作为叶子结点
if(T == NULL) return s;//把新结点*s链接到已找到的插入位置
if(key < f->data)
f -> lchild = s;//将*s插入左子树
else
f -> rchild = s;//将*s插入右子树
return T;
}
void Tree_Delete(BSTree T, int key)//删除指定的节点
{
BSTree p = T,q,f,s;
while(p) //先寻找到要删除的节点
{
if(key == p->data)//找到关键字等于key的结点*p,结束循环
{
break;
}
f = p;//*f为*p的双亲结点
p=(key<p->data)?p->lchild:p->rchild;//在*p的左右子树中继续查找
}
if(!p)
{
cout<<"二叉树中没有节点,不能删除!"<<"\n";
}
else if(!p->lchild && !p->rchild)//被删结点为根结点
{
if(p == T) T=NULL;
if(p == f->lchild)
f->lchild = NULL;//挂接到*f的左子树位置
else
f->rchild = NULL;//挂接到*f的右子树位置
delete p;
p = NULL;
}
else if(!p->rchild && p->lchild)//被删结点*p无右子树,只需重接其左子树
{
if (f->lchild == p)
f->lchild = p->lchild;
else
f->rchild = p->lchild;
delete p;
p = NULL;
}
else if(!p->lchild && p->rchild)//被删结点*p无左子树,只需重接其右子树
{
if(f->lchild == p)
f->lchild = p->rchild;
else
f->rchild = p->rchild;
delete p;
p = NULL;
}
else//被删结点*p左右子树均不空
{
q = p;
s = p->lchild;
while(s->rchild)//在*p的左子树中继续查找其前驱结点,即最右下结点
{
q = s; s = s->rchild;//向右到尽头
}
p->data = s->data;//s指向被删结点的“前驱”
if(q!=p) q->rchild=s->lchild;//重接*q的右子树
else q->lchild = s->lchild;//重接*q的左子树
delete s ;
s = NULL;
}
}
BSTree Create() //创建二叉排序树
{//依次读入一个关键字为key的结点,将此结点插入二叉排序树T中
int key;
BSTree T = NULL;//将二叉排序树T初始化为空树
cout<<"请输入节点数据值:(-1)为结束值"<<endl;
cin>>key;
while(key != -1)
{
T = Tree_Insert(T, key);//将此结点插入二叉排序树T中
cin>>key;
}
return T;
}
void inorder(BSTree T) //中序遍历
{
if(T)
{
inorder(T->lchild);
cout<<T->data<<" ";
inorder(T->rchild);
}
return;
}
void menu()//菜单
{
cout<<" **********欢迎使用************"<<endl;
cout<<" -------1.建立二叉排序树-------"<<endl;
cout<<" -------2.插入节点-------------"<<endl;
cout<<" -------3.删除节点-------------"<<endl;
cout<<" -------4.查找节点-------------"<<endl;
cout<<" -------5.中序遍历-------------"<<endl;
cout<<" -------0.退出系统-------------"<<endl;
cout<<" ******************************"<<endl;
}
int main()
{
int choice1, choice2, key;
BSTree T = NULL;
menu();
do
{
cout<<"请输入你的选择"<<endl;
cin>>choice1;
switch(choice1)
{
case 1:
T = Create();
cout<<"二叉排序树创建成功!"<<endl;
break;
case 2:
cout<<"请输入要插入的节点的关键字:"<<endl;
cin>>key;
T = Tree_Insert(T, key);
cout<<endl;
break;
case 3:
cout<<"请输入要删除的节点的关键字:"<<endl;
cin>>key;
Tree_Delete(T, key);
cout<<endl;
break;
case 5:
cout<<"------中序遍历的结果如下------"<<endl;
inorder(T);
cout<<endl;
break;
case 4:
cout<<"请输入要搜索节点的关键字:"<<endl;
cin>>key;
if(Tree_Search(T, key))
{
cout<<"节点已搜索到!"<<endl;
}
else
{
cout<<"节点不存在!"<<endl;
cout<<"1.插入该节点"<<" "<<"2.不插入该节点"<<endl;
cout<<"请输入你的选择(1-2)"<<endl;
cin>>choice2;
switch(choice2)
{
case 1:
T = Tree_Insert(T, key);
cout<<endl;
break;
case 2:
break;
}
}
}
}while(choice1 != 0);
cout<<endl;
system("pause");
return 0;
}