将一系列给定数字依次插入一个初始为空的小顶堆H[]。随后对任意给定的下标i,打印从H[i]到根结点的路径。
输入格式:
每组测试第1行包含2个正整数N和M(≤1000),分别是插入元素的个数、以及需要打印的路径条数。下一行给出区间[-10000, 10000]内的N个要被插入一个初始为空的小顶堆的整数。最后一行给出M个下标。
输出格式:
对输入中给出的每个下标i,在一行中输出从H[i]到根结点的路径上的数据。数字间以1个空格分隔,行末不得有多余空格。
输入样例:
5 3
46 23 26 24 10
5 4 3
输出样例:
24 23 10
46 23 10
26 10
#include<iostream>
using namespace std;
#define MIN -99999
#define SIZE 10000
struct MinHeap
{
int* Data;
int num;
int capacity;
};
MinHeap* creat()
{
MinHeap* H = (MinHeap*)malloc(sizeof(MinHeap));
H->Data = (int*)malloc(sizeof(int) * SIZE + 1);
H->Data[0] = MIN;
return H;
}
void insert(MinHeap* H, int t)
{
//找到最末子节点
int i = ++H->num;
while (H->Data[i / 2] > t)
{
H->Data[i] = H->Data[i / 2];
i /= 2;
}
H->Data[i] = t;
}
void Mycout(MinHeap* H, int t)
{
int flag = 0;
while (t >= 1)//t 在根结点范围内
{
if (flag)cout << " ";
if (!flag)flag = 1;
cout << H->Data[t];
t /= 2;
}
}
int main()
{
int N, M;
cin >> N >> M;
int t;
MinHeap* H = creat();
for (int i = 0; i < N; i++)
{
cin >> t;
insert(H, t);
}
for (int i = 0; i < M; i++)
{
cin >> t;
Mycout(H, t);
}
return 0;
}
//LJQ 2023 0213 2251
什么是堆排序?
顾名思义就是利用堆来实现对数据的排序
思想: 将待排序的元素建成一个堆(根据从大到小或者从小到大的排序来确定小顶堆或者大顶堆)
下面均以从大到小来举例
第一步:确定建立大(小)顶堆进行筛选调整
void Heap_Adjust(int s, int m)
{
int x = Heap[s];
for (int i = s * 2; i <= m; i *= 2)
{
if (i < m && Heap[i] < Heap[i + 1])i++;
if (x >= Heap[i])break;
Heap[s] = Heap[i];
s = i;
}
Heap[s] = x;
}
第二步:将待排序元素建堆
void Built_Heap()
{
for (int i = Heaplen / 2; i >= 1; i--)
Heap_Adjust(i, Heaplen);
}
第三步:每一次交换堆顶和未排序元素的最后一位元素,每一次排序确定未排序元素中最大值的位置以达到排序的目的
void Heap_sort()
{
Built_Heap();
for (int i = 1; i <= Heaplen; i++)i == Heaplen ? printf("%d \n", Heap[i]) : printf("%d ", Heap[i]);
for (int i = Heaplen; i > 1 ; i--)
{
swap(Heap[1], Heap[i]);
Heap_Adjust(1, i - 1);
for (int i = 1; i <= Heaplen; i++)i == Heaplen ? printf("%d \n", Heap[i]) : printf("%d ", Heap[i]);
}
}
例题一:
例题二