《程序员面试金典》(第六版)习题:仅为记录一下以加强印象,不为商业用途,如有侵权请联系删除。以下源码和解释参考了书中源码以及解释。
以下算法在不断读取数字流时不断进行
v
o
i
d
t
r
a
c
k
(
i
n
t
n
u
m
b
e
r
,
R
a
n
k
N
o
d
e
∗
r
o
o
t
)
void track(int number, RankNode *root)
voidtrack(intnumber,RankNode∗root)操作来对已经读入的数创建一颗二叉搜索树,二叉搜索树中的每一个节点记录了当前树中该节点左子树中节点的个数(即当前节点的秩)。
i
n
t
g
e
t
R
a
n
k
O
f
N
u
m
b
e
r
(
i
n
t
n
u
m
b
e
r
,
R
a
n
k
N
o
d
e
∗
r
o
o
t
)
int getRankOfNumber(int number, RankNode* root)
intgetRankOfNumber(intnumber,RankNode∗root)操作在已经构建好的二叉搜索树中向左寻找某个已经存在于树中的节点(寻找的节点必须存在于二叉树中否则返回-1)的秩时,计数器的值不变,因为向左表明当前节点的值大于要寻找节点的值。当向右寻找时表明当前节点的值小于要寻找节点的值,计数器的值必须加上当前基点的秩,然后还要加一(要寻找的节点也大于当前节点本身)。递归操作直到找到需要寻找的节点为止。
class RankNode
{
public:
int left_size;
RankNode *left;
RankNode *right;
int data;
RankNode(int d = 0)
{
left_size = 0;
data = d;
left= nullptr;
right=nullptr;
}
void insert(int d)
{
if (d <= data)
{
if (left != nullptr)
{
left->insert(d);
}
else
{
left = new RankNode(d);
}
left_size++;
}
else {
if (right != nullptr)
{
right->insert(d);
}
else
{
right = new RankNode(d);
}
}
}
int getRank(int d)
{
if (d == data)
{
return left_size;
}
else if (d < data)
{
if (left == nullptr)
{
return -1;
}
else
{
return left->getRank(d);
}
}
else
{
int right_rank = right == nullptr ? -1 : right->getRank(d);
if (right_rank == -1)
{
return -1;
}
else
{
return left_size + 1 + right_rank;
}
}
}
};
void track(int number, RankNode *root)
{
if (root == nullptr)
{
root = new RankNode(number);
}
else
{
root->insert(number);
}
}
int getRankOfNumber(int number, RankNode* root)
{
return root->getRank(number);
}