バイナリソートツリーとは何ですか?
二分探索木 (bst) は、各ノードがキー値を持ち、次の 2 つの要件を満たす特殊な種類の二分木です。
-
任意のノード x について、その左側のサブツリー上のすべてのノードのキー値は x のキー値より小さくなります。
-
任意のノード x について、そのサブツリー上のすべてのノードのキー値は x のキー値より大きくなります。
上記の 2 つの特性により、バイナリ ソート ツリーは順序付きバイナリ ツリーとも呼ばれます。検索、**、削除などの操作を実行する場合、バイナリソートツリーはバランスを保つことができるため、時間計算量は O(log n) レベルになり、操作効率が大幅に向上します。
バイナリソートツリーの原理
- バイナリ ソート ツリーの各ノードには最大 2 つのサブツリーがあり、左側のサブツリーのすべてのキー (ノード値) は現在のノードのキーより小さく、右側のサブツリーのすべてのキーは現在のノードのキーより大きくなります。現在のノード。
- 左右のサブツリーもバイナリでソートされたツリーです。
- ノードを検索する際、検索対象のキーワードと現在のノードのキーワードのサイズを比較し、等しければ検索成功、等しくない場合は、サイズ関係に従って左または右のサブツリーを対応するまで再帰的に検索します。ノードが見つかりました。ノードが存在しないことをポイントまたは確認します。
- 新しいノードが作成されると、ルート ノードから保留ノードと現在のノードを比較し、サイズの関係に従って左または右にリーフ ノードまで再帰します。次に、新しいノードをリーフ ノードの左側または右側のサブツリーに挿入します。
- ノードを削除するときは、検索方法に従って削除するノードを見つけます。ノードに子ノードがない場合は、そのまま削除します。サブツリーはノードの位置で直接置き換えられます。左のサブツリーと右のサブツリーの両方がある場合は、ノードの位置で直接置き換えられます。サブツリーで、ノードの先行ノードまたは後続ノード (順序トラバーサル中に現在のノードより大きい最小のノード、または現在のノードより小さい最大のノード) ノード) を検索し、その値を使用して削除するノードの値を置き換えます。を選択し、先行者または後続者を削除します。
Java でバイナリ ツリー ソートを実装するサンプル コード:
// 节点类
class Node {
int value;
Node left, right;
public Node(int item) {
value = item;
left = right = null;
}
}
public class BinaryTree {
Node root;
public BinaryTree() {
root = null;
}
// 将给定节点的值插入到二叉树中
private Node insertNode(Node root, int value) {
if (root == null) {
root = new Node(value);
return root;
}
if (value < root.value) {
root.left = insertNode(root.left, value);
} else if (value > root.value) {
root.right = insertNode(root.right, value);
}
return root;
}
// 中序遍历,将节点的值按升序返回。
private void traverseInOrder(Node root, List<Integer> values) {
if (root != null) {
traverseInOrder(root.left, values);
values.add(root.value);
traverseInOrder(root.right, values);
}
}
// 对外的排序方法,接收一个整数数组并返回升序排列后的结果。
public List<Integer> sort(int[] arr) {
for (int i : arr) {
root = insertNode(root, i);
}
List<Integer> sortedList = new ArrayList<>();
traverseInOrder(root, sortedList);
return sortedList;
}
// 测试代码
public static void main(String[] args) {
BinaryTree tree = new BinaryTree();
int[] arr = {
5, 3, 7, 1, 9};
List<Integer> sortedList = tree.sort(arr);
System.out.println(sortedList); // Output: [1, 3, 5, 7, 9]
}
}
この例では、ノード クラスを使用してNode
バイナリ ツリー内の各ノードを表します。バイナリ ツリー クラスには、BinaryTree
ノードの挿入、順序トラバーサル、ソートの 3 つのメソッドが含まれています。
C言語で二分探索木ソートを実装するサンプルコード:
#include <stdio.h>
#include <stdlib.h>
// 定义二叉树节点结构体
struct Node {
int data; // 数据
struct Node* left; // 左子节点指针
struct Node* right; // 右子节点指针
};
// 创建新节点
struct Node* newNode(int data) {
struct Node* node = (struct Node*)malloc(sizeof(struct Node));
node->data = data;
node->left = NULL;
node->right = NULL;
return node;
}
// 插入节点
struct Node* insert(struct Node* node, int data) {
if(node == NULL)
return newNode(data);
if(data < node->data)
node->left = insert(node->left, data);
else if(data > node->data)
node->right = insert(node->right, data);
return node;
}
// 遍历节点并按序排列输出结果
void inorderTraversal(struct Node* node) {
if(node != NULL) {
inorderTraversal(node->left);
printf("%d ", node->data);
inorderTraversal(node->right);
}
}
// 测试示例
int main() {
int arr[] = {
7, 5, 1, 8, 3, 6, 0, 9, 4, 2};
int n = sizeof(arr)/sizeof(arr[0]);
struct Node* root = NULL;
for(int i=0; i<n; i++)
root = insert(root, arr[i]);
inorderTraversal(root);
return 0;
}
上記は単純な二分探索ツリーのソート実装であり、必要に応じて変更および最適化できます。