当合并规模分别为n,m的两个完全二叉堆a和b时,可以考虑一下两种方法:
- 暴力插入:将b的根作为新元素不断插入a中,时间复杂度O(mlogn);
- Floyd建堆:将a、b看成一个整体,使用Floyd建堆算法,时间复杂度O(n);
以上两种方法时间复杂度均不能让我们满足,左式堆的合并时间复杂度可以达到O(logn)
代码:
//
// Created by Jayson on 2023/8/8.
//
#include "BinTree.h"
#include <iostream>
using namespace std;
template<typename T>
class PQ_LeftHeap:public BinTree<T>{
public:
void insert(T e);
T getMax();
T delMax();
};
template<typename T>
int updateNPL(BinNode<T> *v) {//离外部节点的最近距离
if(!v->lchild || !v->rchild){
v->npl = 1;
return 1;
}
int n = updateNPL(v->lchild);
int m = updateNPL(v->rchild);
v->npl = min(n,m)+1;
return v->npl;
}
template<typename T>
BinNode<T>* merge(BinNode<T> *a, BinNode<T> *b) {
if(!a) return b;
if(!b) return a;
if(a->value < b->value)swap(a,b);
a->rchild = merge(a->rchild,b);
a->rchild->parent = a;
updateNPL(a);
if(!a->lchild || a->lchild->npl < a->rchild->npl) swap(a->lchild,a->rchild);
return a;
}
template<typename T>
void PQ_LeftHeap<T>::insert(T e) {
if(!this->_root){
this->_root = new BinNode<T>(e,NULL);
return;
}
BinNode<T>* v = new BinNode<T>(e,NULL);
this->_root = merge(this->_root,v);
this->_root->parent = NULL;
this->_size++;
}
template<typename T>
T PQ_LeftHeap<T>::getMax() {
return this->_root->value;
}
template<typename T>
T PQ_LeftHeap<T>::delMax() {
BinNode<T>* lheap = this->_root->lchild;
BinNode<T>* rheap = this->_root->rchild;
T e = this->_root->value;
delete this->_root;
this->_root = merge(lheap,rheap);
this->_size--;
if(this->_root)this->_root->parent = NULL;
return e;
}