代码中所用到的结构体
typedef struct Node
{
int elem;//存放数据
struct Node *lchild, *rchild;
struct Node *prev;
} TreeNode, *BiTree; //定义树节点的结构体
typedef struct tree
{
BiTree root;
}Tree,*pTree;
构造二叉排序树
- 以第一个输入的数据作为排序二叉树的根。
- 对数数据的输入分为6种情况:
- 1.当树不存在的时候,当前数据作为树的根;
- 2.当树中存在此数据时,打印“此数据已存在”;
- 3.输入数据小于当前结点且当前结点无左儿子,则输入数据作为当前结点的左儿子;
- 4.输入数据小于当前结点且当前结点有左儿子,则将当前结点指针移动到左儿子,继续比较;
- 5.输入数据大于当前结点且当前结点无右儿子,则输入数据作为当前结点的右儿子;
- 6.输入数据大于当前结点且当前结点有右儿子,则将当前结点指针移动到右儿子,继续比较;
- 结束条件为输入 -1
void CreateBST(pTree T)//构造二叉排序树
{
int e=0;//初始化
while(1)//while循环建立二叉排序树
{
printf("Please input the child of BST:");
printf("(input will over when you input -1.)\n");
scanf("%d",&e);//插入的数据
getchar();
if(e==-1)//非法判断
{
break;
}
BiTree n1=(BiTree)malloc(sizeof(TreeNode));//申请空间
BiTree n2=T->root;//初始化
n1->elem=e;
n1->lchild=NULL;
n1->rchild=NULL;
n1->prev=NULL;
if(T->root==NULL)//当树不存在时
{
T->root=n1;
}
else//当树存在时
{
while(1)//实现二叉树插入
{
if(e==n2->elem)//若树中存在此元素
{
printf("this elem has existed!\n");
break;
}
if(e>n2->elem&&n2->rchild==NULL)
{
n2->rchild=n1;
n1->prev=n2;
break;
}
else if(e>n2->elem)
{
n2=n2->rchild;
}
else if(e<n2->elem&&n2->lchild==NULL)
{
n2->lchild=n1;
n1->prev=n2;
break;
}
else if(e<n2->elem)
{
n2=n2->lchild;
}
}
}
}
}
删除二叉排序树的结点
删除可能出现的几种情况
- 二叉排序树不存在。
- 二叉排序树中无将删除的结点。
- 二叉排序树中存在要删除的结点,并执行删除。
这里,我对第三种查找到了二叉排序树中存在该节点并删除进行展开讨论。
二叉排序树中的删除节点的三种情况
1.即将删除的节点为叶结点。
- 执行方法,将该叶结点删除,且将原本指向该叶结点的指针指向NULL;
2.即将删除的节点仅存在左子树或者仅存在右子树。(这里以仅存在左子树为例)
- 寻找即将删除节点的左子树的最右下节点(即左子树中的最大结点),将其赋值给即将删除的结点,赋值完成后再对该最右下结点进行处理。
- 这里要注意的是,这里删除节点的值被左子树中最大结点覆盖的同时,左子树中的最大结点也要随之删除,这里也要对其讨论是否存在左子树进行讨论。
3.即将删除的结点即存在右子树,也存在左字数。
- 这里有两种选择,以左子树中的最右下结点(即左子树中的最大结点)进行替换,或是以右子树中的最左下节点(即右子树中的最小结点)进行替换。
- 同样要注意的是,在替换的时候,要对被拿去替换的点进行讨论,看其是否存在左子树,或右子树。
void DeleteNode(pTree T)//删除二叉排序树的结点
{
int e;
BiTree n=T->root;
BiTree n1=NULL;
BiTree n2=NULL;
printf("Please input the elem you want to delete:\n");
scanf("%d"