二分探索木の中間順の次節点

Harshit Jindal 2023年10月12日
  1. BST アルゴリズムにおける中間順の次節点
  2. BST での中間順の次節点
  3. BST の実装における中間順の次節点
  4. BST アルゴリズムにおける中間順の次節点の複雑性
二分探索木の中間順の次節点

二分木の中間順の次節点は、二分木の中間順探索で次に来るノードです。つまり、ツリー内の最後のノードは NULL です。二分探索木の中間順探索はソートされた配列であるので、次のノードは NULL です。与えられたノードよりも小さいキーを持つノードをその順不同の後継ノードと定義します。BST では、中間順の次節点には 2つの可能性があり、そのノードの右サブツリーまたは祖先の中で値が最も小さいノードが中間順後継者となります。そうでない場合、そのノードの中間順の次節点は存在しません。

BST アルゴリズムにおける中間順の次節点

  • root == NULL ならば、succNULL に設定して返します。
  • root->data < current->data ならば、succcurrentcurrentcurrent->left とします。
  • root->data > current->data の場合、currentcurrent->right とします。
  • root->data == current->dataroot->right != NULL の場合、succ = minimum(current->right).
  • succ を返します。

BST での中間順の次節点

二分探索木

3 には右ノードがあり、 4 は右サブツリーの 3 よりも大きい最小ノードであるため、 3 の中間順の次節点は 4 です。

4 には正しいノードがないため、 4 の中間順の次節点は 5 であり、その祖先を調べる必要があります。その中で、 54 よりも大きい最小のノードです。

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
Harshit Jindal avatar Harshit Jindal avatar

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

関連記事 - Data Structure

関連記事 - Binary Tree

関連記事 - Binary Search Tree