#include <stdio.h>
#include <stdlib.h>
typedef int KeyType; // 定义节点关键码的类型为整型
typedef struct node // 二叉排序树的结构体
{
KeyType key; // 树节点的关键码
struct node *lchild, *rchild; // 左右孩子指针
} node, *BiSortTree;
void CreateBST(BiSortTree *T); // 构造二叉排序树
void InsertBST(BiSortTree *T, KeyType x); // 向T中插入关键码值为 x 的节点
void DeleteBST(BiSortTree *T, KeyType x); // 删除T中关键码值为 x 的节点
void TraverseBST(BiSortTree T); // 中序遍历BST
int SearchBST(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f);
int SearchBST_Recursive(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f);
// 在T中查找关键码值为 x 的节点,若找到则返回1,p指向该节点,f指向该节点双亲节点;否则返回0
int main(void)
{
BiSortTree T, p, f;
p = f = NULL;
CreateBST(&T);
printf("遍历:");
TraverseBST(T);
printf("\n");
printf("查找 98 :");
int flag = SearchBST(T, 98, &p, &f);
if (flag)
printf("查找成功!\n");
else
printf("查找失败!\n");
printf("递归查找 100 :");
flag = SearchBST_Recursive(T, 100, &p, &f);
if (flag)
printf("查找成功!\n");
else
printf("查找失败!\n");
printf("插入 100 :");
InsertBST(&T, 100);
TraverseBST(T);
printf("\n");
printf("删除 98 :");
DeleteBST(&T, 98);
TraverseBST(T);
printf("\n");
return 0;
}
void CreateBST(BiSortTree *T) // 构造二叉排序树
{
KeyType x;
printf("请输入若干整数构建BST,以 -1 结束:");
*T = NULL;
scanf("%d", &x);
while (x != -1) {
InsertBST(T, x);
scanf("%d", &x);
}
}
// 在T中查找关键码值为 x 的节点,若找到则返回1,*p指向该节点,*f为*p双亲节点;否则返回0
int SearchBST(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f)
{
*p = T;
while (*p) {
// 查找成功
if ((*p)->key == x)
return 1;
else {
// 在左子树继续查找
if (x < (*p)->key) {
*f = *p;
*p = (*p)->lchild;
}
// 在右子树继续查找
else {
*f = *p;
*p = (*p)->rchild;
}
}
}
return 0; // 查找失败
}
int SearchBST_Recursive(BiSortTree T, KeyType x, BiSortTree *p, BiSortTree *f)
{
// 树空时,查找失败
if (!T)
return 0;
// 查找成功
else if (x == T->key) {
*p = T;
return 1;
}
// 在左子树继续查找
else if (x < T->key)
return SearchBST_Recursive(T->lchild, x, p, &T);
// 在右子树继续查找
else
return SearchBST_Recursive(T->lchild, x, p, &T);
}
void InsertBST(BiSortTree *T, KeyType x) // 向T中插入关键码值为 x 的节点
{
BiSortTree p, f, s;
f = p = NULL;
// 若树中不存在关键码值为 x 的节点,则插入
if (!SearchBST(*T, x, &p, &f)) {
s = (node *)malloc(sizeof(node)); // 申请节点并赋值
s->key = x;
s->lchild = NULL;
s->rchild = NULL;
// 若树为空,将新申请的节点作为根节点
if (!*T)
*T = s;
else {
// 插入节点为f的左孩子
if (x < f->key)
f->lchild = s;
// 插入节点为f的右孩子
else
f->rchild = s;
}
}
}
void DeleteBST(BiSortTree *T, KeyType x) // 删除T中关键码值为 x 的节点
{
BiSortTree p, f, s, s_parent;
/**
* p:要删除的节点
* f:p的双亲结点
* s:p的中序前驱节点
* s_parent:s的双亲结点
*/
p = f = NULL;
// 若树中存在关键码值为 x 的节点,则删除
if (SearchBST(*T, x, &p, &f)) {
// 被删除节点无左右孩子
if (!p->lchild && !p->rchild) {
// 若删除的是根节点
if (p == *T) {
*T = NULL;
free(p);
}
// 若删除的不是根节点
else {
if (p->key < f->key)
f->lchild = NULL;
else
f->rchild = NULL;
free(p);
}
}
// 被删除节点有右孩子无左孩子
else if (!p->lchild && p->rchild) {
// 若删除的是根节点
if (p == *T) {
*T = p->rchild;
free(p);
}
// 若删除的不是根节点
else {
if (p->key < f->key)
f->lchild = p->rchild;
else
f->rchild = p->rchild;
free(p);
}
}
// 被删除节点有左孩子无右孩子
else if (p->lchild && !p->rchild) {
// 若删除的是根节点
if (p == *T) {
*T = p->lchild;
free(p);
}
// 若删除的不是根节点
else {
if (p->key < f->key)
f->lchild = p->lchild;
else
f->rchild = p->lchild;
free(p);
}
}
// 被删除节点有左右孩子
else {
s_parent = p;
s = p->lchild;
while (s->rchild) // 查找被删除节点中序前驱节点
{
s_parent = s;
s = s->rchild;
}
p->key = s->key;
if (s_parent == p)
s_parent->lchild = s->lchild;
else
s_parent->rchild = s->lchild;
free(s);
}
}
}
void TraverseBST(BiSortTree T) // 中序遍历BST
{
if (T) {
TraverseBST(T->lchild);
printf("%d, ", T->key);
TraverseBST(T->rchild);
}
}
二叉排序树
最新推荐文章于 2024-07-23 22:38:49 发布