二叉查找树(4) - 中序查找一个给定值的前驱以及后继

假设树的节点定义如下,查找一个指定值的前驱以及后继节点。如果树中没有找到指定值,则返回它所在区间的边界值。
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

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值