二分探索木の中間順の次節点
二分木の中間順の次節点は、二分木の中間順探索で次に来るノードです。つまり、ツリー内の最後のノードは NULL
です。二分探索木の中間順探索はソートされた配列であるので、次のノードは NULL
です。与えられたノードよりも小さいキーを持つノードをその順不同の後継ノードと定義します。BST では、中間順の次節点には 2つの可能性があり、そのノードの右サブツリーまたは祖先の中で値が最も小さいノードが中間順後継者となります。そうでない場合、そのノードの中間順の次節点は存在しません。
BST アルゴリズムにおける中間順の次節点
root
==NULL
ならば、succ
をNULL
に設定して返します。root->data
<current->data
ならば、succ
をcurrent
、current
をcurrent->left
とします。root->data
>current->data
の場合、current
をcurrent->right
とします。root->data
==current->data
でroot->right
!=NULL
の場合、succ
=minimum(current->right)
.succ
を返します。
BST での中間順の次節点
3
には右ノードがあり、 4
は右サブツリーの 3
よりも大きい最小ノードであるため、 3
の中間順の次節点は 4
です。
4
には正しいノードがないため、 4
の中間順の次節点は 5
であり、その祖先を調べる必要があります。その中で、 5
は 4
よりも大きい最小のノードです。
BST の実装における中間順の次節点
#include <iostream>
using namespace std;
class Node {
public:
int data;
Node *left, *right;
Node(int x) {
this->data = x;
this->left = this->right = NULL;
}
};
Node* insert(Node* root, int key) {
if (root == NULL) {
return new Node(key);
}
if (key < root->data) {
root->left = insert(root->left, key);
} else {
root->right = insert(root->right, key);
}
return root;
}
Node* getNextleft(Node* root) {
while (root->left) {
root = root->left;
}
return root;
}
void inorderSuccessor(Node* root, Node*& succ, int key) {
if (root == NULL) {
succ = NULL;
return;
}
if (root->data == key) {
if (root->right) {
succ = getNextleft(root->right);
}
}
else if (key < root->data) {
succ = root;
inorderSuccessor(root->left, succ, key);
} else {
inorderSuccessor(root->right, succ, key);
}
}
int main() {
int keys[] = {1, 5, 8, 2, 6, 3, 7, 4};
Node* root = NULL;
for (int key : keys) {
root = insert(root, key);
}
for (int key : keys) {
Node* prec = NULL;
inorderSuccessor(root, prec, key);
if (prec) {
cout << "Inorder successor of node " << key << " is " << prec->data;
} else {
cout << "No inorder Successor of node " << key;
}
cout << '\n';
}
return 0;
}
BST アルゴリズムにおける中間順の次節点の複雑性
時間計算量
- 平均ケース
平均的なケースでは、BST の中から順不同の後継者を見つける時間の複雑さは、二分探索木の高さのオーダーです。平均すると、BST の高さは O(logn)
です。これは、形成された BST がバランスのとれた BST である場合に発生します。したがって、時間の複雑さは [Big Theta]: O(logn)
のオーダーです。
- 最良の場合
ベストケースは木がバランスのとれた BST である場合です。ベストケースの削除の時間複雑度は O(logn)
のオーダーです。これは平均ケースの時間複雑度と同じです。
- 最悪の場合
最悪の場合、ルートから最深部のリーフノードまで、つまり木の高さ h
全体を移動しなければならないかもしれません。木が不均衡である場合、すなわち、木が歪んでいる場合、木の高さは n
になるかもしれません。
空間の複雑さ
アルゴリズムの空間の複雑さは、再帰呼び出しに必要な余分な空間があるため、O(h)
となります。
Harshit Jindal has done his Bachelors in Computer Science Engineering(2021) from DTU. He has always been a problem solver and now turned that into his profession. Currently working at M365 Cloud Security team(Torus) on Cloud Security Services and Datacenter Buildout Automation.
LinkedIn