任务描述
本关任务:给出一个待插入的序列,设计出在二叉排序树中插入结点的算法,将序列的每个数字依次插入初始为空二叉排序树,在此基础上实现构建二叉排序树的算法。
相关知识
动态查找表的表结构在查找过程中动态生成,对于给定值key,在表中查找,若存在,则成功返回;否则插入关键字等于key 的记录。
二叉排序树是一种动态查找表,将数据元素构造成二叉排序树的优点:
- 查找过程与顺序结构有序表中的折半查找相似,查找效率高;
- 中序遍历此二叉树,将会得到一个关键字的有序序列(即实现了排序运算);
- 一个无序序列可以通过构造一棵二叉排序树而变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。
- 如果查找不成功,能够方便地将被查元素插入到二叉树的叶子结点上,而且插入或删除时只需修改指针而不需移动元素。
这种既查找又插入的过程称为动态查找。二叉排序树既有类似于折半查找的特性,又采用了链表存储,它是动态查找表的一种适宜表示。
二叉排序树的二叉链存储结构的结点的类型声明如下:
typedef struct
{
KeyType key;
}ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode *lchild,*rchild
}BSTNode,*BSTree;
二叉排序树的插入结点的算法
例如,输入待查找的关键字序列=(45,24,53,45,12,24,90),则生成二叉排序树的过程为: 第1步:插入45
第2步:插入24
第3步:插入53
第4步:插入45,查找成功,返回
第5步:插入12
第6步:插入24,查找成功,返回
第7步:插入90
- 先在二叉排序树
bt
中查找插入新结点的位置,由于二叉排序树中所有新结点都是作为叶子结点插入的,所以这里是查找插入新结点的双亲即f
结点。 - 然后建立一个关键字为k的结点p。
- 若
bt
为空树,则p
结点作为根结点。 - 若
k<f->key
,将p
结点作为f
结点的左孩子插入。 - 若
k>f->key
,将p
结点作为f
结点的右孩子插入。
int BSTInsert(BSTree &T, ElemType e )
{
if (!T) //确定要插入
{
s = new BSTNode;
s->data = e;
s->lchild = s->rchild = NULL;
T = s; // 被插结点 *s 为新的根结点
}
else if ( e.key < T->data.key )
BSTInsert(T.lchild,e);
else if ( e.key > T->data.key )
BSTInsert(T.rchild,e);
} // BSTInsert
编程要求
请在右侧编辑器的命名空间内填写相关代码,给出一个待插入的序列,实现将序列的每个数字依次插入初始为空二叉排序树的算法。
- 创建二叉排序树CreateBST(bt,str,n):由关键字数组str建立一棵二叉排序树bt;
- 销毁二叉排序树DestroyBST(bt):释放二叉排序树bt中所有结点的内存空间;
- 插入结点InsertBST(bt,k):在二叉排序树bt中插入关键字为k的结点;
- 中序遍历二叉排序树TraverseBST(dt);
测试说明
平台会对你编写的代码进行测试:
右侧数据框说明: 测试输入: 第一行 1 个整数 n 表示序列的大小 第二行 n 个整数表示序列里的元素 实际输出: 输出你返回的二叉排序树中序遍历的序列
#include <stdio.h>
#include <malloc.h>
#define N 100
typedef int KeyType; // 设关键字域为整型
typedef int InfoType;
typedef struct
{
KeyType key;
InfoType otherinfo;
}ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode *lchild,*rchild;
}BSTNode,*BSTree;
int InsertBST(BSTNode *&bt,KeyType k);
void CreateBST(BSTNode *&bt,KeyType a[],int n);
void DestroyBST(BSTNode *&bt);
void TraverseBST(BSTree dt, void (*print)(ElemType) );
void visit(ElemType i);
int main()
{
BSTree dt=NULL,p=NULL,f=NULL;
int i,n;
KeyType j;
KeyType r[N]={0};
scanf("%d",&n);
for(i=0;i<n;i++)
scanf("%d",&r[i] ); // 依次插入数据元素
CreateBST(dt,r,n);
TraverseBST(dt, visit);
DestroyBST(dt);
}
void visit(ElemType i)
{
printf("%d\n",i.key );
}
int InsertBST(BSTree &T,KeyType e)
{
/********** Begin **********/
if (!T){
BSTNode * s = new BSTNode;
s -> data.key = e;
s->lchild = s->rchild = NULL;
T = s;
}
else if(e < T->data.key){
InsertBST(T->lchild,e);
}
else if(e > T->data.key){
InsertBST(T->rchild,e);
}
/********** End **********/
}
void CreateBST(BSTNode *&bt,KeyType a[],int n)
{
/********** Begin **********/
bt = NULL;
int i = 0;
while (i < n){
InsertBST(bt, a[i]);
i++;
}
/********** End **********/
}
void TraverseBST(BSTree dt, void (*print)(ElemType) )
{
/********** Begin **********/
if(dt){
TraverseBST(dt->lchild, print);
print(dt->data);
TraverseBST(dt->rchild, print);
}
/********** End **********/
}
void DestroyBST(BSTNode *&bt)
{
/********** Begin **********/
if (bt){
DestroyBST(bt->lchild);
DestroyBST(bt->rchild);
delete bt;
bt = NULL;
}
/********** End **********/
}