数据结构 05-树7 堆中的路径 (25 分)
将一系列给定数字插入一个初始为空的小顶堆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
小顶堆的建立 堆顶元素删除
因为小顶堆/大顶堆是一种线性结构, 堆顶是最小/最大元素, 调整堆的时候要 层序遍历 或 逆层序遍历 来比较并交换父子结点元素内容, 使用线性结构数组来存储数据便于修改
广度遍历都应该使用线性结构来存储数据
深度遍历应该使用堆栈来存储数据
这题是蒙对的
排序过程与书中的不同, 虽然正确 但是浪费了许多不必要的时间,待改进
参考文章https://blog.csdn.net/liyuanyue2017/article/details/84328364
//小顶堆的建立 查找 #include <iostream> #include <vector> typedef int elementType; using namespace std; class tnode{ public: elementType data; tnode* left{nullptr}; tnode* right{nullptr}; tnode()=default; tnode(elementType d):data{d}{}; }; class minHeap{ public: tnode* root; vector<int> heap; minHeap()=default; void build(int n){ int temp; for(int i=0;i<n;i++){ cin >> temp; heap.push_back(temp); adjustHeapFromBack(); } } void adjustHeapFromBack(){ for(int i=heap.size()-1;i>=0&&heap.size()>1;i--){ if(heap[i]<heap[(i-1)/2]){ swap(heap[i], heap[(i-1)/2]); } } } void adjustHeapFromFront(){ for(int i=1;i<heap.size()-1&&heap.size()>1;i++){ if(heap[i]<heap[(i-1)/2]){ swap(heap[i], heap[(i-1)/2]); } } } int popMin(){ if(heap.size()){ int result=heap[0]; swap(heap[0], heap[heap.size()-1]); heap.pop_back(); adjustHeapFromFront(); return result; }else{ return -1; } } void showPathToRoot(int n){ int i=n-1; while(i>0){ cout << heap[i]<<" "; i=(i-1)/2; } if(heap.size()){ cout << heap[0]; } cout <<endl; } }; int main(){ int n,m,temp; minHeap heap; cin >> n >> m; heap.build(n); for(int i=0;i<m;i++){ cin >> temp; heap.showPathToRoot(temp); } return 0; }