关于堆的判断 (25 分)

关于堆的判断 (25 分)_第1张图片
基础知识:
大顶堆:每个结点的值都大于或等于其左右孩子结点的值
小顶堆:每个结点的值都小于或等于其左右孩子结点的值
二叉堆就是一颗二叉树,是一颗完全二叉树

定义两个操作:
down(int k ):从编号为k的点向下更新
up(int k) :从编号为k的点向上更新

h[]堆数组,size堆当前大小
堆的变化(都可以由上面定义的两个操作来实现):
1.插入一个数 -> h[++ size] = x; up(size)
2.求集合中的最小值 -> h[1]
3.删除最小值 -> h[1] = h[size]; size --; down(1)
4.删除任意一个元素 -> h[k] = h[size]; size --; down(k); up(k);
5.修改任意一个元素 -> h[k] = x; down(k); up(k);

两个操作的具体代码实现(以小根堆为例):

void down (int u)
{
	int t = u;	//t存储当前位置和左右儿子的最小节点
	if (2 * u <= size1 && h[2 * u] < h[t])	t = 2 * u;
	if (2 * u + 1 <= size1 && h[2 * u + 1] < h[t]) t = 2 * u + 1;
	if (u != t)//如果父节点大于其中的儿子节点需要down操作
	{
		swap (h[u], h[t]);
		down (t);
	}
}

void up(int u)
{
    while(u/2 && h[u/2]>h[u])	//父结点的值大于儿子节点需要交换
    {
        h_swap(u/2,u);
        u/=2;
    }
}

本题只需要up操作
AC代码:

#include 
using namespace std;
const int N = 1e5 + 10; 
int in[N], pre[N];
int n, m;
int h[N];
int cnt = 0;


void up (int u)
{
	while (u / 2 && h[u] < h[u / 2])
	{
		swap (h[u], h[u / 2]);
		u /= 2;
	}
}
int main ()
{
	cin >> n >> m;
	for (int i = 1; i <= n; i ++)
	{
		int x; cin >> x;
		h[++ cnt] = x;
		up (i);
	} 
	map<int, int> mp;
	for (int i = 1; i <= n; i ++) mp[h[i]] = i;
	while (m --)
	{
		int x; cin >> x;
		string s; cin >> s;
		if (s == "is")
		{
			string s2; cin >> s2;
			if (s2 == "the")
			{
				string s3; cin >> s3;
				if (s3 == "root")
				{
					if (mp[x] == 1)
						cout << "T" << "\n";
					else 
						cout << "F" << "\n";
				}
				else
				{
					string s4; int x2;
					cin >> s4 >> x2;
					if (mp[x] == mp[x2] / 2)
						cout << "T" << "\n";
					else 
						cout << "F" << "\n";
				}
			}
			else
			{
				string s3, s4;	int x2;
				cin >> s3 >> s4 >> x2;
				if (mp[x] / 2 == mp[x2])
					cout << "T" << "\n";
				else 
					cout << "F" << "\n";
			}
		}
		else
		{
			int x2;
			string s2, s3;
			cin >> x2 >> s2 >> s3;
			if (mp[x] / 2 == mp[x2] / 2) 
				cout << "T" << "\n";
			else 
				cout << "F" << "\n";
		}
	}
	
}

你可能感兴趣的:(算法,c++)