//查找某一个存在节点的前驱和后继。某一个节点x的后继就是大于key[x]的关键字中最小的那个节点,前驱就是小于key[x]的关键字中最大的那个节点。查找二叉前驱和后继节点的算法如下所示:
typedef struct _node {
struct _node *left_child;
struct _node *right_child;
struct _node * parent;
ctypedata;
}node; //树节点数据结构定义
typedef node* Tree;
//查找二叉查找树中的关键字,返回指向该节点的指针
Tree tree_search(Tree root, ctype data)
{
Tree p = root;
while (p != null && data != p->data) {
if (data < p->data) {
p = p->left_child;
}
else {
p = p->right_child;
}
}
return p;
}
//查找二叉查找树中关键字最小的节点,返回指向该节点的指针
Tree tree_minimum(Tree root)
{
Tree p = root;
while (p->left_child != null) {
p = p->left_child;
}
return p;
}
//查找二叉查找树中关键字最大的节点,返回指向该节点的指针
Tree tree_maxmum(Tree root)
{
Tree p = root;
while (p->right_child != null)
{
p = p->right_child;
}
return p;
}
//查找二叉查找树中节点x的后继节点,返回指向该节点的指针
//在查找过程中,如果节点x右子树不为空,那么返回右子树的最小节点即可
//如果节点x的右子树为空,那么后继节点为x的某一个祖先节点的父节点,而且该祖先节点是作为其父节点的左儿子
Tree tree_successor(Tree x)
{
if (x->right_child != null)
return tree_minimum(x->right_child);
//x用来保存待确定的节点
//y为x的父节点
Tree y = x->parent;
while (y != NULL && x == y->right_child)
{
x = y;
y = y->parent;
}
return y;
}
//查找二叉查找树中节点x的前驱节点,返回指向该节点的指针
//在查找过程中,如果节点x左子树不为空,那么返回左子树的最大节点即可
//如果节点x的左子树为空,那么前驱节点为x的某一个祖先节点的父节点,而且该祖先节点是作为其父节点的右儿子
Tree tree_predecessor(Tree x)
{
if (x->left_child != null)
return tree_maxmum(x->left_child);
Tree y = x->parent;
while (y != NULL && x == y->left_child)
{
x = y;
y = y->parent;
}
return y;
}
//在二叉树中插入一个节点,这个节点一定是成为叶子节点
//保持father指针为遍历指针p的双亲
void tree_search(Tree root, node *n) {
node * parent = NULL, p = root;
//使得两个遍历指针向下移动,找到合适的插入位置
while (p != NULL) {
parent = p;
if (n->data < p->data) {
p = p->left_child;
}
else {
p = p->right_child;
}
}
n->parent = parent;
//如果是一棵空树
if (parent == NULL) {
root = n;
}
//成为左节点还是右节点
else if (n->data < parent->data) {
parent->left_child = n;
}
else
{
parent->right_child = n;
}
}