二叉搜索树找前驱和后继

输入N个数,找每个数的前驱和后继。如果没有前驱或后继,输出-1;

思路:

如果有右子树,则右子树的最小值为当前节点的后继;否则后继为当前节点往祖先搜索,第一次是左孩子的节点的父亲的值;

如果有左子树,则左子树的最大值为当前节点的前驱;否则前驱为当前节点往祖先搜索,第一次是右孩子的节点的父亲的值;

#include "bits/stdc++.h"
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
struct BST {
    int value;
    BST* father;
    BST* lson;
    BST* rson;
}* root;
BST* init(int val) {
    BST* point = (BST*)malloc(sizeof(BST));
    point->value = val;
    point->lson = point->rson = NULL;
    return point;
}
void insert(int val) {
    BST* father = NULL;
    BST* now = root;
    while (now != NULL) {
        if (now->value == val) {
            return;
        }
        father = now;
        if (now->value < val) {
            now = now->rson;
        } else {
            now = now->lson;
        }
    }
    if (father == NULL) {
        root = init(val);
        root->father = NULL;
    } else if (father->value < val) {
        father->rson = init(val);
        father->rson->father = father;
    } else {
        father->lson = init(val);
        father->lson->father = father;
    }
}
int minOfBST(BST* point) {
    while (point->lson != NULL) {
        point = point->lson;
    }
    return point->value;
}
int maxOfBST(BST* point) {
    while (point->rson != NULL) {
        point = point->rson;
    }
    return point->value;
}
int precursor (int val) {
    BST* point = root;
    while (point != NULL) {
        if (point->value == val) {
            if (point->lson != NULL) {
                return maxOfBST(point->lson);
            } else {
                while (point->father != NULL && point->father->rson != point) {
                    point = point->father;
                }
                if (point->father == NULL){
                    return -1;
                } else {
                    return point->father->value;
                }
            }
        }
        if (val > point->value) {
            point = point->rson;
        } else {
            point = point->lson;
        }
    }
}
int successor (int val) {
    BST* point = root;
    while (point != NULL) {
        if (point->value == val) {
            if (point->rson != NULL) {
                return minOfBST(point->rson);
            } else {
                while (point->father != NULL && point->father->lson != point) {
                    point = point->father;
                }
                if (point->father == NULL){
                    return -1;
                } else {
                    return point->father->value;
                }
            }
        }
        if (val > point->value) {
            point = point->rson;
        } else {
            point = point->lson;
        }
    }
}
int main() {
    int N, val;
    queue<int>q;
    scanf("%d", &N);
    while (N--) {
        scanf("%d", &val);
        insert(val);
        q.push(val);
    }
    while (!q.empty()) {
        printf("%d ", precursor(q.front()));
        printf("%d\n", successor(q.front()));
        q.pop();
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Angel-Demon/p/10222685.html

时间: 2024-11-05 15:56:53

二叉搜索树找前驱和后继的相关文章

二叉搜索树的前驱和后继详细推导

后继和前驱 定义:一个结点的后继,是大于x.key的最小关键字的结点. 一个结点的前驱,是小于x.key的最大关键字的结点. 思路:找一个结点的前驱或者后继,无非是在三个区域找. 首先分析前驱: 满足两个条件,一是要小于当前键值,那么只有LP和LS区可以找. 二要求是其中最大的值.我们知道,对于LP来说,X.LS.RS都属于他的右子树,那么,X.LS和RS都是大于它的. 所以很显然,前驱就是LS中的最大值,即前驱 = 左子树中的最大值.条件是:存在左子树. 那不存在左子树只有左父母的情况呢? 那

求二叉搜索树的前驱节点和后继节点

前驱结点:节点val值小于该节点val值并且值最大的节点 后继节点:节点val值大于该节点val值并且值最小的节点 二叉树的节点val值是按照二叉树中序遍历顺序连续设定. 前驱结点 如图4的前驱结点是3 2的前驱结点是1 6的前驱结点是5 后继节点 7的后继结点是8 5的后继节点是6 2的后继节点是3 前驱节点 若一个节点有左子树,那么该节点的前驱节点是其左子树中val值最大的节点(也就是左子树中所谓的rightMostNode) 若一个节点没有左子树,那么判断该节点和其父节点的关系 2.1 若

C++实现二叉搜索树的常用操作

实现操作 (1)二叉搜索树的建立 (2)二叉搜索树的插入 (3)二叉搜索树的三种递归遍历(前序.中序和后续) (4)二叉搜索树的三种非递归遍历(前序.中序和后续) (5)二叉搜索树的逐层打印 (6)搜索某一个字符(递归算法) (7)搜索一个字符(非递归算法) (8)查找最大元素 (9)查找最小元素 有时间再实现: (10)二叉搜索树的前驱和后继查找 (11)二叉搜索树的删除 源码分析: #include <iostream> #include <stack> #include &l

二叉搜索树JavaScript实现

* 什么是二叉搜索树?其形式就是二叉树,对于每个节点x,其左子树的值<=x.value,右子树的值>=x.value. * 对于二叉搜索树,我们可以使用中序遍历,得到树上从小到大所有的元素.时间复杂度平均为O(n). function inorderTreeWalk(x) { if(x!== null) { inorderTreeWalk(x.left); print(x.key); inorderTreeWalk(x.right); } } * 当我们想要查询二叉搜索树中某个关键字应该怎么做

二叉搜索树建立、插入、删除、前继节点、后继节点之c++实现

一.前言 一直以来,都对树有关的东西望而却步.以前每次说要看一看,都因为惰性,时间就那么荒废掉了.今天下个决心,决定好好的数据结构中的东西看一下.不知道看这篇文章的你,是不是和我有同样的感受,空有一颗努力的心,却迟迟没有付出行动.如果是的话,如果也想好好的把树的知识巩固一下的话,就让我们一起好好儿地把知识点过一遍吧.本文争取让看完的每一个没有基础的同学,都能有所收获.在正文开始前,先给自己加个油.加油(^ω^) 二.二叉搜索树的定义 二叉搜索树是指,对于某一个节点而言,它左边的节点都小于或等于它

剑指Offer(Java版)第六十五题:给定一棵二叉搜索树,请找出其中的第k小的结点。 例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4。

/*给定一棵二叉搜索树,请找出其中的第k小的结点.例如, (5,3,7,2,4,6,8) 中,按结点数值大小顺序第三小结点的值为4.*//*二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值: 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值*///思路:从最左边的叶子节点开始找起. import java.util.*; public clas

Java数据结构之二叉搜索树

Java数据结构之二叉搜索树 1.二叉搜索树组成 二叉搜索树又称为二叉排序树,它或者是一颗空树,或者是一颗具有如下特性的非空二叉树,需要满足一下三个条件: (1)若它的左子树非空,则左子树上所有结点的关键字均小于根结点的关键字: (2)若它的右子树非空,则右子树上所有结点的关键字均大于(可以等于)根结点的关键字. (3)左子树右子树本身又各是一颗二叉搜索树 在算法描述中,均以结点值的比较来代表其关键字的比较,因为若结点的值为类类型时,该类必须实现系统提供的java.lang.comparable

二叉搜索树&mdash;&mdash;算法导论(14)

1. 什么是二叉搜索树     顾名思义,二叉搜索树是以一棵二叉搜索树来组织的.如下图,这样的一棵树可以使用一个链表数据结构来表示,其中的每一个节点是一个对象.除了key和卫星数据之外,每个节点还包含属性left(左孩子).right(右孩子).和p(双亲)(若不存在,则值为NIL).     二叉搜索树中的关键字总是以满足二叉搜索树性质的方式存储: 设x是二叉搜索树的一个节点.如果y是x左子树中的一个节点,那么y.key≤x.key.如果y是x右子树中的一个节点,那么y.key≥x.key.

数据结构-二叉搜索树(BST binary search tree)

本文由@呆代待殆原创,转载请注明出处:http://www.cnblogs.com/coffeeSS/ 二叉搜索树简介 顾名思义,二叉搜索树是以一棵二叉树来组织的,这样的一棵树可以用一个链表数据结构来表示,每个节点除了key和卫星数据(除了二叉树节点的基本数据以外人为添加的数据,这些数据和树的基本结构无关),还有left.right.parent,分别指向节点的左孩子.右孩子和父节点,如果对应的节点不存在则指向NIL节点(因为最简单的二叉搜索树中的NIL节点里并没有有用的信息,所以在实现的时候简