Чтобы получить преемника-преемника данного узла N
, мы используем следующие правила:
- Если
N
имеет правильного ребенка R
, то
inorderSuccessor(N)
самый левый
потомок R
.
- Остальное
inorderSuccessor(N)
является ближайшим
предок, M
, из N
(если он существует)
такой, что N
происходит от
оставленный ребенок M
. Если такого предка нет, inorderSucessor не существует.
Рассмотрим пример дерева:
A
/ \
B C
/ \
D E
/
F
Чей обход по порядку дает: D B F E A C
inorderSuccessor(A)
= C
, поскольку C
является самым левым потомком правого ребенка A
.
inorderSuccessor(B)
= F
, поскольку F
является самым левым потомком правого ребенка B
.
inorderSuccessor(C)
= Не существует.
inorderSuccessor(D)
= B
, поскольку B
является левым потомком D
.
inorderSuccessor(E)
= A
. E
не имеет правильного потомка, поэтому у нас есть сценарий 2. Мы переходим к родителю E
, который равен B
, но E
является прямым потомком B
, поэтому мы переходим к родителю B
A
, а B
является потомком A
, поэтому A
является ответом.
inorderSuccessor(F)
= E
, поскольку F
является левым потомком E
.
Процедура:
treeNodePtr inorderSucessor(treeNodePtr N) {
if(N) {
treeNodePtr tmp;
// CASE 1: right child of N exists.
if(N->right) {
tmp = N->right;
// find leftmost node.
while(tmp->left) {
tmp = tmp->left;
}
// CASE 2: No right child.
} else {
// keep climbing till you find a parent such that
// node is the left decedent of it.
while((tmp = N->parent)) {
if(tmp->left == N) {
break;
}
N = tmp;
}
}
return tmp;
}
// No IOS.
return NULL;
}
Код в действии