大小堆操作
来源:互联网 发布:网络借贷监管暂行办法 编辑:程序博客网 时间:2024/06/16 19:27
大小堆的概念:
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树 的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2*i+1 且 Ki<= K2*i+2 (Ki >= K2*i+1 且 Ki >= K2*i+2) i = 0,1,2…,则称这个堆为最小堆(或最大 堆)。
最小堆:任一结点的关键码均小于等于它的左右孩子的关键码,位于堆顶结点的关键码最小
最大堆:任一结点的关键码均大于等于它的左右孩子的关键码,位于堆顶结点的关键码最大
对于堆主要的是堆的插入和删除引起的调整过程:
由于堆的插入和删除会引起堆不在符合大小堆的性质,从而引发调整;
大小堆的比较器:
template<typename T>//小堆比较器class Less{public: bool operator()(T& left, T& right) { return left < right; }};template<typename T>//大堆比较器class High{public: bool operator()(T& left, T& right) { return right>left; }};
模板:
template < class T,class Compera = Less<T>>
大小堆的创建过程:
Heap(const T array[], size_t size) //创建一个堆 { _heap.resize(size); //堆得大小一次性分配够了 for(size_t idx=0;idx<size;++idx) { //_heap.push_back(array[idx]); _heap[idx]=array[idx]; //将数组里面的元素逐个拷贝进创建的堆中 cout<<_heap[idx]<<" "; } cout<<endl; // 找倒数第一个非叶子结点 int root = (_heap.size()-2)>>1; for (; root >= 0; root--) _AdjustDown(root); for(int i = 0; i<_heap.size(); i++) cout<<_heap[i]<<" "; cout<<endl; } protected: std::vector<T> _heap;};
由底向上调整
void AdjustDown(int root) //自底而上进行调整 { root=((_heap.size()-2)>>1); //从倒数第一个非叶子节点开始 for (; root >= 0; root--) { _AdjustDown(root); } for(int i = 0; i<_heap.size(); i++) cout<<_heap[i]<<" "; cout<<endl; } void _AdjustDown(int root)//自底而上进行调整 { size_t child=root*2+1; //左孩子 size_t size=_heap.size(); while(child < size) //左孩子的大小是否小于堆的大小 { if(child + 1 < size &&Compera()(_heap[child+1], _heap[child])) //比较左右孩子大小 child+=1; //如果左孩子大于右孩子 if(Compera()(_heap[child], _heap[root])) { std::swap(_heap[root],_heap[child]); //双亲结点大于孩子结点,交换两个结点多大的位置 root=child; child=root*2+1; } else return; } }
有顶至下调整:
void AdjustUp(size_t root)//自顶而下进行调整 { for (int idx=0;idx<root;idx++) { _AdjustUp(idx); } for (int i=0;i<_heap.size();i++) { cout<<_heap[i]<<" "; } cout<<endl; } void _AdjustUp(size_t parent) { size_t child=_heap.size()-1; parent=(child-1)>>1; while (child != 0) { if (Compera()(_heap[child], _heap[parent])) { std::swap(_heap[parent], _heap[child]); child = parent; parent = (child - 1) / 2; } else break; } }
堆结点的插入:堆的插入每次都在已经建成的而最小堆的后面插入,但插入之后,有可能破坏了对的 结构,这时就需要对堆进行重新调整。
void Insert(const T& data) //向已创建的堆中插入元素 { size_t size = _heap.size()+1; _heap.push_back(data); AdjustUp(size); }
堆的删除:从堆中删除堆顶元素。移除堆顶元素之后,用堆的最后一个节点填补取 走的堆顶元素,并将堆的实际元素个数减1。但用最后一个元素取代堆顶元素之后有可 能破坏堆,因此需要将对自顶向下调整,使其满足最大或最小堆。
void Remove() //移除堆中的元素 { assert(!_heap.empty()); size_t size = _heap.size(); std::swap(_heap[0], _heap[size - 1]); _heap.pop_back(); _AdjustDown(size-1); }
阅读全文
0 0
- 大小堆操作
- 大小堆之堆排序
- 堆大小的最大值
- 估计堆的大小
- 堆大小设置
- 堆 栈 大小端
- 栈堆大小端
- 数据结构--大小堆
- 堆大小设置
- 大小堆的建立
- 大小堆 排序
- 大小堆实现
- 大小顶堆
- windbg 计算堆大小
- 堆操作
- 堆操作
- jvm 堆内存 栈内存 大小设置 查看堆大小
- JVM堆大小的调整
- 简单服务器——Node.js
- xshell连接本机虚拟机里的Linux环境
- Android 悬浮窗显示
- 块设备驱动再次剖析
- 最短路 【卡io】
- 大小堆操作
- Sublime Text 更改主题 详细图解
- Docker官方入门教程
- 安卓控件拖动和点击事件冲突处理----可拖动的FloatingActionButton
- 快速排序
- 精品拍卖系统技术解析 从拍品分类中获取所有拍品
- 通过封装的AsyncTask类实现下载apk应用
- 对卿学姐的一道题目的自己的理解
- Windows8.1系统上安装Linux--openSUSE64