05-树7 堆中的路径 (25分)

将一系列给定数字插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。

输入格式:

每组测试第1行包含2个正整数NNMM(\le 10001000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的NN个要被插入一个初始为空的小顶堆的整数。最后一行给出MM个下标。

输出格式:

对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。

输入样例:

5 3
46 23 26 24 10
5 4 3

输出样例:

24 23 10
46 23 10
26 10
1、以逐个插入的方式建堆

#include <stdio.h>
#include <stdlib.h>

#define MAXN 1001
#define MINH -10001
#define ERROR -1

void Create();
void Insert(int ElemX);

int MinH[MAXN];
int size;
int main()
{
	int i, j, n, m, ElemX;

	scanf("%d %d\n", &n, &m);
	
	Create();
	for (i = 0; i < n; i++)
	{
		scanf("%d", &ElemX);
		Insert(ElemX);
	}

	for (i = 0; i < m; i++)
	{
		scanf("%d", &j);
		printf("%d", MinH[j]);
		while (j>1)
		{
			j /= 2;
			printf(" %d", MinH[j]);
		}
		printf("\n");
	}

	system("pause");
	return 0;
}

void Create()
{
	MinH[0] = MINH; // 设置哨岗
	size = 0;
}

void Insert(int ElemX)
{
	int i;

	if (size >= MAXN)
	{
		printf("最小堆已满!");
		return;
	}
	for (i = ++size; MinH[i / 2] > ElemX; i /= 2)
		MinH[i] = MinH[i / 2];
	MinH[i] = ElemX;
}


2、两步法建堆-----先按完全二叉树的结构顺序插入元素,然后调整各个节点的位置

输出的结果和逐步插入法的结果不一样


#include <stdio.h>
#include <stdlib.h>

#define MAXN 1000
#define MINH -10001
#define ERROR -1

typedef int ElementType;
typedef struct HeapStruct *MinHeap;
struct HeapStruct {
	ElementType *Elements;
	int Size;
	int Capacity;
};


MinHeap Create(int MaxSize);
void Insert(MinHeap H, int size);
void BulidHeap(MinHeap H);
void PercDown(MinHeap H, int Pos);

int main()
{
	int i, j, n=0, m=0;
	
	scanf("%d %d\n", &n, &m);
	
	MinHeap H = Create(MAXN);
	Insert(H, n);

	BulidHeap(H);

	for (i = 1; i <= H->Size; i++)
		printf("%d ", H->Elements[i]);

	for (i = 0; i < m; i++)
	{
		scanf("%d", &j);
		printf("%d", H->Elements[j]);
		while (j>1)
		{
			j /= 2;
			printf(" %d", H->Elements[j]);
		}
		printf("\n");
	}

	system("pause");
	return 0;
}

MinHeap Create(int MaxSize)
{
	MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
	H->Elements = (ElementType*)malloc(sizeof(ElementType)*(MaxSize + 1));
	H->Elements[0] = MINH;
	H->Size = 0;
	H->Capacity = MaxSize;

	return H;
}

/*顺序插入元素*/
void Insert(MinHeap H, int size)
{
	int i;
	ElementType ElemX;
	for (i = 1; i <= size; i++)
	{
		scanf("%d", &ElemX);
		H->Elements[i] = ElemX;
		H->Size++;
	}
}

/*调整元素的位置使其成为最小堆*/
void BulidHeap(MinHeap H)
{
	int i;
	for (i=H->Size/2; i >0; i--)
	{
		PercDown(H, i);
	}
}

/*向下过滤函数*/
void PercDown(MinHeap H, int Pos)
{
	int Parent, Child;

	ElementType X;
	X = H->Elements[Pos];
	for (Parent = Pos; Parent * 2 <= H->Size; Parent = Child)
	{
		Child = Parent * 2;
		if (Child != H->Size && (H->Elements[Child] > H->Elements[Child + 1]))
			Child++;
		if (X <= H->Elements[Child])
			break;
		else
			H->Elements[Parent] = H->Elements[Child];
	}
	H->Elements[Parent] = X;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值