📜  将BST转换为Max Heap(1)

📅  最后修改于: 2023-12-03 14:53:45.884000             🧑  作者: Mango

将BST转换为Max Heap

什么是BST和Max Heap
  • BST(二叉搜索树)是一种特殊的二叉树,它的每个节点最多有两个子节点,左子节点小于等于父节点,右子节点大于等于父节点。
  • Max Heap(最大堆)是一种满足以下条件的完全二叉树:任何一个非叶子节点的值都不大于其左右子节点的值。
转换方法

BST与Max Heap的区别在于它们的结构。而将BST转换为Max Heap的方法则需要改变它们的数值关系。

  1. 遍历BST,将其节点的值存储在一个数组中。
  2. 对数组进行heapify操作,将其转换为一个Max Heap。heapify操作的具体实现可使用Heap Sort中的方法。
  3. 将数组中的数值一个一个赋值回BST。
转换过程示例代码
以Python为例
class Node:
    def __init__(self, data):
        self.data = data
        self.left = None
        self.right = None

def inorderTraversal(root, arr):
    if not root:
        return
    inorderTraversal(root.left, arr)
    arr.append(root.data)
    inorderTraversal(root.right, arr)

def maxHeapify(arr, i, n):
    largest = i
    l = 2 * i + 1
    r = 2 * i + 2

    if l < n and arr[l] > arr[largest]:
        largest = l

    if r < n and arr[r] > arr[largest]:
        largest = r

    if largest != i:
        arr[i], arr[largest] = arr[largest], arr[i]
        maxHeapify(arr, largest, n)

def convertBSTtoMaxHeap(root):
    arr = []
    inorderTraversal(root, arr)
    n = len(arr)

    for i in range(n // 2 - 1, -1, -1):
        maxHeapify(arr, i, n)

    i = 0
    j = n - 1
    while i <= j:
        root.data = arr[j]
        j -= 1

        if i <= j:
            root.left = Node(arr[j])
            j -= 1

        if i <= j:
            root.right = Node(arr[j])
            j -= 1

        root = root.left
    return root

该Python代码中,使用了Inorder Traversal遍历了BST,并将节点值存储在一个数组中。接着,对数组进行了heapify操作,将其转换为最大堆。最后,使用数组中的值重新构建了BST。时间复杂度为O(nlogn)。

以C++为例
#include <iostream>
#include <vector>
#include <queue>
using namespace std;

struct Node {
    int data;
    Node* left, * right;
    Node(int d) : data(d), left(nullptr), right(nullptr) {}
};

void inorderTraversal(Node* root, vector<int>& arr) {
    if (!root) return;
    inorderTraversal(root->left, arr);
    arr.push_back(root->data);
    inorderTraversal(root->right, arr);
}

void maxHeapify(vector<int>& arr, int i, int n) {
    int largest = i;
    int l = 2 * i + 1;
    int r = 2 * i + 2;

    if (l < n && arr[l] > arr[largest])
        largest = l;

    if (r < n && arr[r] > arr[largest])
        largest = r;

    if (largest != i) {
        swap(arr[i], arr[largest]);
        maxHeapify(arr, largest, n);
    }
}

Node* convertBSTtoMaxHeap(Node* root) {
    vector<int> arr;
    inorderTraversal(root, arr);
    int n = arr.size();

    for (int i = n / 2 - 1; i >= 0; i--) {
        maxHeapify(arr, i, n);
    }

    queue<Node*> q;
    q.push(root);
    int i = 1;

    while (i < n) {
        Node* cur = q.front();
        q.pop();

        cur->left = new Node(arr[i++]);
        q.push(cur->left);

        if (i < n) {
            cur->right = new Node(arr[i++]);
            q.push(cur->right);
        }
    }
    return root;
}

void printInorderTraversal(Node* root) {
    if (root) {
        printInorderTraversal(root->left);
        cout << root->data << " ";
        printInorderTraversal(root->right);
    }
}

int main() {
    Node* root = new Node(4);
    root->left = new Node(2);
    root->right = new Node(6);
    root->left->left = new Node(1);
    root->left->right = new Node(3);
    root->right->left = new Node(5);
    root->right->right = new Node(7);

    cout << "Inorder Traversal of BST: ";
    printInorderTraversal(root); // 1 2 3 4 5 6 7
    cout << endl;

    root = convertBSTtoMaxHeap(root);

    cout << "Inorder Traversal of Max Heap: ";
    printInorderTraversal(root); // 7 6 5 4 3 2 1
    cout << endl;

    return 0;
}

该C++代码同样是使用Inorder Traversal遍历了BST,并将节点值存储在了一个vector中。接着,对vector进行了heapify操作,将其转换为最大堆。最后,使用vector中的值重新构建了BST。

总结

将BST转换为Max Heap需要分为以下步骤:

  1. 遍历BST,将其节点的值存储在一个数组中。
  2. 对数组进行heapify操作,将其转换为一个Max Heap。
  3. 将数组中的数值一个一个赋值回BST。

该方法的时间复杂度为O(nlogn)。