数据结构三
左偏树可能各个方面都是最优的,可能他的最大缺点是插入操作O(n),但是综合并操作与代码难度考虑还是不错的选择
至于他的已知节点删除和变种没实现,待以后用的话再补上吧,觉得几乎没用处?(
不敢说XD...
/****************************************
* LeftHeap.h
* Describe: 可并优先队列——左偏树
* Created: 2010-5-27
* CopyRight 2010,Leek
*
******************************************/
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
typedef int Type;
typedef struct LNode
{
Type key;
int dis;
LNode *left;
LNode *right;
LNode (Type key)
{
dis = 0;
left = NULL;
right = NULL;
this->key = key;
}
}LNode;
typedef LNode *PLNode;
void Swap (int &a, int &b)
{
a ^= b, b ^= a, a ^= b;
}
void Swap (PLNode &a, PLNode &b)
{
PLNode tmp = a;
a = b, b = tmp;
}
PLNode LHeap_Merge (PLNode a,PLNode b)
{
if (a == NULL)
return b;
if (b == NULL)
return a;
if (a->key > b->key)
Swap (a->key,b->key);
a->right = LHeap_Merge (a->right, b);
if (a->left == NULL || a->right->dis > a->left->dis)
Swap (a->right,a->left);
if (a->right == NULL)
a->dis = 0;
else
a->dis = a->right->dis + 1;
return a;
}
PLNode LHeap_Build (queue<PLNode> &a)
{
PLNode tmp = a.front();
while (a.size() > 1)
{
a.pop();
tmp = LHeap_Merge (tmp,a.front());
a.push(tmp);
a.pop();
tmp = a.front();
}
return a.front();
}
PLNode LHeap_Insert (Type key,PLNode root)
{
PLNode tmp = new LNode(key);
return LHeap_Merge (tmp,root);
}
Type LHeap_Delete_Min (PLNode &root)
{
PLNode tmp = root;
root = LHeap_Merge (root->left, root->right);
Type top = tmp->key;
delete tmp;
return top;
}
觉得建树和并操作值得思考多少有点启发性吧
顺便贴上败者树的模板 今天复习结束看漫画去![]()
/****************************************
* Loser.h
* Describe: 败者树
* Created: 2010-5-27
* CopyRight 2010,Leek
*
******************************************/
#include <iostream>
using namespace std;
const int N = 1 << 16; //N大于n,并为2的次方
const int n = 234;
typedef int Type;
Type f[N * 2];
Type a[n];
void BuildTree (int n, int f[2 * N])
//建树a存在f N-N+n
{
memcpy (f + N,a,sizeof (a[0]) *n);
for (int i = N,j = N + n - 1; i > 1;i >>= 1,j >>= 1)
{
for (int k = i; k < j;k += 2)
f[k >> 1] = f[k] > f[k + 1] ? f[k] : f[k + 1];
//求得是最大值,可改为最小值
if (!(j&1))
f[j >> 1] = f[j];
}
}
int findmax (int s, int t)
//查询s t中的最大 最小值
{
int r = f[s] >= f[t]? s: t;
for (int i = s,j = t; i < j; i >>= 1, j >>= 1)
{
if (!(i & 1) && i + 1 < j && f[i + 1] > f[r])
r = i + 1;
if ((j & 1) && j - 1 > i && f[j - 1] > f[r])
r = j - 1;
}
return f[r];
//以下程序可求a【s t】最大最小值的下标
while (r < N)
if (f[r] == f[r << 1])
r <<= 1;
else
if (f[r] == f[(r << 1) + 1])
r = (r << 1) + 1;
}