假设树的节点定义如下,查找一个指定值的前驱以及后继节点。如果树中没有找到指定值,则返回它所在区间的边界值。
struct Node
{
int key;
Node *left,*right ;
};
下面是实现此操作的算法,采用递归。
//输入: 根节点(root), 键值(key)
//输出: 前驱节点, 后继节点
1. 如果root==null
then return
2. 如果找到了key
a. 左子树不为null
则前驱为左子树的最右侧的孩子节点, 或者就是左孩子本身.
b. 右子树不为null
则后继为右子树的最左侧的孩子节点, 或者就是右孩子本身.
return
3. 如果key小于root节点
将后继节点设置为root
递归搜索左子树
else
将前驱节点设置为root
递归搜索右子树
下面是基于上面算法的C++代码实现:
// BST中查找前驱和后继的C++程序
#include <iostream>
struct Node {
int key;
Node* left;
Node* right;
};
//在BST中查找指定值的前驱和后继,分别保存在pre和suc中。
void findPreSuc(Node* root, int key, Node*& pre, Node*& suc) {
// 空树
if (root == NULL)
return;
// 找到匹配的节点
if (root->key == key) {
// 左子树中最大值为前驱
if (root->left != NULL) {
Node* tmp = root->left;
while (tmp->right)
tmp = tmp->right;
pre = tmp;
}
// 右子树中最小值为后继
if (root->right != NULL) {
Node* tmp = root->right;
while (tmp->left)
tmp = tmp->left;
suc = tmp;
}
return;
}
// 指定值小于根节点值,继续查找左子树
if (root->key > key) {
suc = root;
findPreSuc(root->left, key, pre, suc);
}
else //查找右子树
{
pre = root;
findPreSuc(root->right, key, pre, suc);
}
}
// 创建一个新的BST节点
Node* createNewNode(int item) {
Node* temp = new Node;
temp->key = item;
temp->left = temp->right = NULL;
return temp;
}
//插入新节点至二叉搜索树中
Node* insert(Node* node, int key) {
//空树
if (node == NULL)
return createNewNode(key);
//递归插入。如果已存在指定值,则不插入
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
//返回未修改的node指针
return node;
}
// 中序遍历二叉搜索树
void inorder(Node* root) {
if (root != NULL) {
inorder(root->left);
std::cout << " " << root->key << " ";
inorder(root->right);
}
}
int main() {
/* 构建一颗如下所示的BST
55
/ \
33 77
/ \ / \
22 44 66 88
*/
Node* root = NULL;
root = insert(root, 55);
insert(root, 33);
insert(root, 22);
insert(root, 44);
insert(root, 77);
insert(root, 66);
insert(root, 88);
Node* pre = NULL, * suc = NULL;
int key = 59;
findPreSuc(root, key, pre, suc);
if (pre != NULL)
std::cout << "Predecessor is " << pre->key << std::endl;
else
std::cout << "No Predecessor\n";
if (suc != NULL)
std::cout << "Successor is " << suc->key << std::endl;
else
std::cout << "No Successor\n";
return 0;
}
运行结果:
Predecessor is 55
Successor is 66