📅  最后修改于: 2023-12-03 15:39:22.785000             🧑  作者: Mango
左派树与左派堆都是一种基于二叉树的数据结构,它们在某些场景下能够提供比传统数据结构更加优秀的性能。
左式堆是一种二叉树,它具有以下性质:
这样的数据结构相比传统的二叉堆多了一个rank值的属性,左子树rank值大于等于右子树rank值的属性使得左式堆具有一定的左偏性质。由于左偏性质,左式堆能够在合并两棵堆的函数中进行优化,使得合并两棵堆的时间复杂度能够达到O(logN)。
左式堆的主要操作包括建堆、插入节点、删除堆顶节点、合并两个堆。
以下是一个简单的左式堆的C++实现(仅包含合并操作):
template<typename T>
struct Node {
T value;
Node* left;
Node* right;
int rank;
Node() : value(0), left(nullptr), right(nullptr), rank(1) {}
Node(T v) : value(v), left(nullptr), right(nullptr), rank(1) {}
};
template<typename T>
class LeftistHeap {
public:
LeftistHeap() : root(nullptr) {}
void merge(Node<T>* left, Node<T>* right) {
if (left == nullptr) {
root = right;
return;
}
if (right == nullptr) {
root = left;
return;
}
if (left->value > right->value) swap(left, right);
left->right = merge(left->right, right);
if (left->left == nullptr || left->left->rank < left->right->rank) swap(left->left, left->right);
left->rank = (left->right == nullptr) ? 0 : left->right->rank + 1;
root = left;
}
private:
Node<T>* root;
};
左偏树是一种基于左式堆的数据结构,它主要通过path compression来优化合并和删除操作。
和左式堆不同的是,左偏树中的节点不再需要保证左子树rank值不小于右子树rank值。因为它同时具有左式堆和右式堆的性质,所以被称作左偏堆。
左偏树中的主要操作包括建树、插入节点、删除堆顶节点、合并两个堆。
以下是一个简单的左偏树的C++实现(仅包含合并操作):
template<typename T>
struct Node {
T value;
Node* left;
Node* right;
int rank;
Node() : value(0), left(nullptr), right(nullptr), rank(0) {}
Node(T v) : value(v), left(nullptr), right(nullptr), rank(0) {}
};
template<typename T>
class LeftistTree {
public:
LeftistTree() : root(nullptr) {}
void merge(Node<T>* left, Node<T>* right) {
if (left == nullptr) {
root = right;
return;
}
if (right == nullptr) {
root = left;
return;
}
if (left->value > right->value) swap(left, right);
left->right = merge(left->right, right);
if (left->left == nullptr || left->left->rank < left->right->rank) swap(left->left, left->right);
left->rank = (left->right == nullptr) ? 0 : left->right->rank + 1;
// path compression
if (root != left && left->left == nullptr && left->rank > 1 && left->rank > left->right->rank + 1) {
swap(left->left, left->right);
left->rank = left->right->rank + 1;
}
root = left;
}
private:
Node<T>* root;
};
左派树与左派堆是一种基于二叉树的数据结构,它们的合并操作能够达到O(logN)的时间复杂度。左派树在左式堆的基础上进行了优化,加入了path compression的策略,性能比左式堆更加优秀。左派树在实际应用中能够解决一些复杂度较高的场景,比如任务调度、最大割问题等。