数据结构三

 左偏树可能各个方面都是最优的,可能他的最大缺点是插入操作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;
}