#include<stdio.h>
#include<stdlib.h>
typedef int type;
typedef struct bst //创建结构体
{
type data;
struct bst *left, *right;
struct bst *parent;
}node, *tree;
static node* create_node(type data, node *left, node *right, node *parent) //创建结点
{
node *p;
p = (node*)malloc(sizeof(node));
p->left = left;
p->right = right;
p->parent = parent;
p->data = data;
/* printf("创造结点完毕");*/
return p;
}
node* search_(tree x, type key)
{
if (x == NULL || x->data == key)
{
return x;
}
if (key < x->data)
{
return search_(x->left, key);
}
else
{
return search_(x->right, key);
}
} //递归查找
node* search(tree y, type key)
{
while (y != NULL && y->data != key)
{
if (y->data < key)
y = y->right;
else
y = y->left;
}
return y;
} //迭代查找
node* max(tree m) //最大值
{
if (m == NULL)
return NULL;
while (m->right != NULL)
{
m = m->right;
}
return m;
}
node* min(tree m) //最小值
{
if (m == NULL)
return NULL;
while (m->left != NULL)
{
m = m->left;
}
return m;
}
node* successor(node *s) //后继
{
if (s->right != NULL) //结点右子树非空
return min(s->right);
else
{
node* p = s->parent; //结点是左孩子,后继就是他的父节点
while (p != NULL && p->right == s)
{ //结点是右孩子,向上查找,直到遇到一个有左孩子的父节点,那就是后继
{
s = p;
p = p->parent;
}
}
return p;
}
}
node* insert(tree t, node *z) //将建好的结点插入进二叉树里
{
node *y = NULL;
node *i;
i = t;
while (i != NULL)
{
y = i; //循环完了之后y是i的父节点
if (i->data < z->data)
i = i->right;
else
i = i->left;
}
z->parent = y;
if (y == NULL) //整棵树在插入之前都是空的
t = z;
else if (z->data < y->data)
y->left = z;
else
y->right = z;
return t;
}
node* insert_(tree t, type k) //建立一个结点,没有连接
{
node *z;
z = create_node(k, NULL, NULL, NULL);
return insert(t, z);
}
node* deletes(tree d, node* z) //删除
{
tree x = NULL, y = NULL;
if (z->left == NULL || z->right == NULL) //z至多有一个子女
y = z;
else //z有两个子女
y = successor(z);
if (y->left != NULL) //y(也就是z,或z的后继)如果有子女,将它赋给x
x = y->left;
else
x = y->right;
if (x != NULL) //x如果得到了y赋的值(也就是z的子女或者后继的子女)
x->parent = y->parent;
if (y->parent == NULL) //如果y是根节点
d = x;
else if (y == y->parent->left) //如果y是左子女
y->parent->left = x;
else //如果y是右子女
y->parent->right = x;
if (y != z) //y不等于z就是等于后继,z有两个子女的情况,就把后继的值拿给z
z->data = y->data;
return d;
}
node* delete_(tree t, type k)
{
node* z=NULL;
z = search_(t, k);
if (z != NULL)
{
printf("查找");
t = deletes(t, z);
printf("删除完了");
}
else
printf("无此元素");
return t;
}
void print_tree(tree t) //中序遍历打印
{
if (t)
{
print_tree(t->left);
printf("%d ", t->data);
print_tree(t->right);
}
}
int main()
{
int i;
tree zz = NULL, yy = NULL,kk=NULL,gg=NULL;
type k;
int a[12] = { 15,5,16,3,12,10,13,6,7,20,18,23 };
printf("\n原来的数字是:----------------------------------------");
for (i = 0; i<12; i++)
{
printf("%d ", a[i]);
zz = insert_(zz, a[i]);
}
/* printf("插入完毕");*/
printf("\n中序遍历结果是:------------------------------------");
print_tree(zz);
printf("\n最大值是:-------------------------------------------");
printf("%d ", max(zz)->data);
printf("\n请输入要查找的值:--------------------------------");
scanf_s("%d", &k);
search_(zz, k);
if (search_(zz, k) != NULL)
printf("查找成功");
else
printf("无此元素");
printf("\n要查找的后继是:---------------------------------");
scanf_s("%d", &k);
kk=search_(zz, k);
gg=successor(kk);
printf("%d", gg->data);
printf("\n要删除的值是:---------------------------------------");
scanf_s("%d", &k);
yy = delete_(zz, k);
print_tree(yy);
printf("\n要插入的值是:--------------------------------------");
scanf_s("%d", &k);
insert_(zz, k);
print_tree(zz);
}
参照了算法导论的伪代码和https://www.cnblogs.com/skywang12345/p/3576328.html这位博主的代码
感觉自己主函数写得好乱。。。。