当前位置:实例文章 » HTML/CSS实例» [文章]平衡二叉搜索树--AVL详解剖析

平衡二叉搜索树--AVL详解剖析

发布人:shili8 发布时间:2025-01-04 14:30 阅读次数:0

**平衡二叉搜索树—AVL详解**

平衡二叉搜索树(Balanced Binary Search Tree)是计算机科学中一个重要的数据结构,它能够保证在插入、删除操作后,树的高度始终保持相对稳定的状态。这使得它成为许多应用场景中的首选选择。

本文将详细介绍AVL树(Adelson-Velskii and Landis),一种最著名的平衡二叉搜索树。我们将讨论其定义、性质、构造方法以及插入和删除操作的实现。

**定义**

AVL树是一种自平衡的二叉搜索树,每个节点都有一个高度(height),它是从根到该节点的最大深度。对于任何结点,左子树和右子树都是平衡的,即它们的高度差不超过1。

**性质**

AVL树具有以下重要性质:

* **自平衡性**:AVL树保证在插入或删除操作后,树的高度始终保持相对稳定的状态。
* **搜索效率**:由于AVL树是二叉搜索树,每次查找都能以O(log n)时间复杂度完成。
* **插入和删除效率**:虽然AVL树在插入或删除操作时可能需要进行旋转来维持平衡,但其平均时间复杂度仍然为O(log n)。

**构造方法**

AVL树的构造方法非常简单。我们可以将其视为一个普通的二叉搜索树,然后在每次插入或删除操作后,通过检查当前结点及其子结点的高度差来决定是否需要进行旋转。

**插入操作**

当我们向AVL树中插入一个新结点时,我们首先将其作为叶结点添加到树中。然后,我们从根结点开始向下遍历,直到找到一个位置可以插入新结点的父结点。

在这个过程中,我们需要检查当前结点及其子结点的高度差。如果高度差超过1,我们就需要进行旋转来维持平衡。

**删除操作**

当我们从AVL树中删除一个结点时,我们首先找到该结点的父结点,然后将其替换为其孩子结点之一。然后,我们再次向上遍历,直到找到一个位置可以更新高度差的父结点。

在这个过程中,我们需要检查当前结点及其子结点的高度差。如果高度差超过1,我们就需要进行旋转来维持平衡。

**示例代码**

下面是AVL树的示例代码:

cpp#include <iostream>
using namespace std;

// 结点结构体struct Node {
 int key;
 Node* left;
 Node* right;
};

// AVL树类class AVLTree {
public:
 // 构造函数 AVLTree() : root(nullptr) {}

 // 销毁函数 ~AVLTree() { destroy(root); }

 // 插入函数 void insert(int key) {
 Node* newNode = new Node();
 newNode->key = key;
 newNode->left = nullptr;
 newNode->right = nullptr;

 root = insertNode(root, newNode);
 }

 // 删除函数 void remove(int key) {
 root = removeNode(root, key);
 }

 // 查找函数 bool search(int key) {
 return searchNode(root, key);
 }

private:
 Node* root; // 根结点 // 插入结点函数 Node* insertNode(Node* node, Node* newNode) {
 if (node == nullptr) {
 return newNode;
 }

 if (newNode->key < node->key) {
 node->left = insertNode(node->left, newNode);
 } else if (newNode->key > node->key) {
 node->right = insertNode(node->right, newNode);
 } else {
 // 重复键值 return node;
 }

 // 更新高度差 int leftHeight = getHeight(node->left);
 int rightHeight = getHeight(node->right);

 if (abs(leftHeight - rightHeight) >1) {
 // 左子树高于右子树 if (leftHeight > rightHeight) {
 return rotateRight(node, newNode);
 } else {
 return rotateLeft(node, newNode);
 }
 }

 return node;
 }

 // 删除结点函数 Node* removeNode(Node* node, int key) {
 if (node == nullptr) {
 return node;
 }

 if (key < node->key) {
 node->left = removeNode(node->left, key);
 } else if (key > node->key) {
 node->right = removeNode(node->right, key);
 } else {
 // 找到结点 Node* temp = node;
 if (node->left == nullptr && node->right == nullptr) {
 return nullptr; // 无孩子结点 }

 if (node->left == nullptr) {
 return node->right; // 只有右孩子结点 }

 if (node->right == nullptr) {
 return node->left; // 只有左孩子结点 }

 // 有两个孩子结点 Node* temp = findMin(node->right);
 node->key = temp->key;
 node->right = removeNode(node->right, key);
 }

 // 更新高度差 int leftHeight = getHeight(node->left);
 int rightHeight = getHeight(node->right);

 if (abs(leftHeight - rightHeight) >1) {
 // 左子树高于右子树 if (leftHeight > rightHeight) {
 return rotateRight(node, nullptr);
 } else {
 return rotateLeft(node, nullptr);
 }
 }

 return node;
 }

 // 查找结点函数 bool searchNode(Node* node, int key) {
 if (node == nullptr) {
 return false; // 未找到 }

 if (key < node->key) {
 return searchNode(node->left, key);
 } else if (key > node->key) {
 return searchNode(node->right, key);
 } else {
 return true; // 找到结点 }
 }

 // 旋转函数 Node* rotateLeft(Node* node, Node* newNode) {
 Node* temp = node->right;
 node->right = temp->left;
 temp->left = node;

 if (newNode != nullptr) {
 newNode->key = temp->key;
 }

 return temp;
 }

 Node* rotateRight(Node* node, Node* newNode) {
 Node* temp = node->left;
 node->left = temp->right;
 temp->right = node;

 if (newNode != nullptr) {
 newNode->key = temp->key;
 }

 return temp;
 }

 // 获取高度函数 int getHeight(Node* node) {
 if (node == nullptr) {
 return0; // 高度为0 }

 return1 + max(getHeight(node->left), getHeight(node->right));
 }

 // 销毁函数 void destroy(Node* node) {
 if (node != nullptr) {
 destroy(node->left);
 destroy(node->right);
 delete node;
 }
 }
};

int main() {
 AVLTree tree;

 tree.insert(5);
 tree.insert(3);
 tree.insert(7);
 tree.insert(2);
 tree.insert(4);
 tree.insert(6);
 tree.insert(8);

 cout << "是否存在键值5: " << (tree.search(5) ? "是" : "否") << endl;
 cout << "是否存在键值9: " << (tree.search(9) ? "是" : "否") << endl;

 tree.remove(3);
 cout << "是否存在键值3: " << (tree.search(3) ? "是" : "否") << endl;

 return0;
}

上述代码实现了一个基本的AVL树类,支持插入、删除和查找操作。

其他信息

其他资源

Top