数据结构--二叉堆与堆排序
来源:互联网 发布:读懂中国经济数据 编辑:程序博客网 时间:2024/05/31 19:40
- 二叉堆的概念
二叉堆,BinaryHeap,是二叉树中的常见的一种结构。通常以最大堆和最小堆的形式呈现。最大堆指的是父节点大于等于孩子节点的value值,也就是说对于最大堆而言,根元素是二叉堆最大的元素。最小堆的概念是与最大堆的概念是相似的。下图是最大堆的示意图:
- 二叉堆和排序之间的联系
二叉堆最显著的特征就是根元素是二叉树元素间最大的或者最小的。因此每次将二叉树最大或者最小的元素取出来,同时保证每次进行这样的操作后,剩下的元素依然可以保持二叉堆的性质,这样迭代这个过程,就可以完成排序的目的。
所以,进行堆排序的过程,首先就需要进行待排序元素的堆建立过程。这里以最大堆为例。
堆的建立过程
在建立最大堆的过程中,每插入一个元素,就要对元素进行一个上浮的操作。上浮是指对每个即将插入最大堆的元素进行判断,判断与当前元素与其父元素的大小关系,保持父元素与孩子元素之间的大小关系,重复这个过程,直到从根元素开始,所有的父元素和孩子元素都和二叉堆的定义保持一致。具体实现过程如下:
首先是最大堆的ADT:
template<class T>class BinaryHeap{public: BinaryHeap(int capacity); ~BinaryHeap(); void filterUp(int start); void Insert(T &data); T delHeap(); void BuildHeap(vector<T> initArray); void displayHeap();private: T *m_pData; int mCurSize; int mCapacity;};然后是最大堆的建立过程:
template<class T>void BinaryHeap<T>::filterUp(int start){ int nIndex=start; T temp=m_pData[nIndex]; int parentIndex=(int) start/2; while(nIndex>0) { if(m_pData[parentIndex]<temp) { m_pData[nIndex]=m_pData[parentIndex]; nIndex=parentIndex; parentIndex=(int) nIndex/2; } else break; } m_pData[nIndex]=temp;}template<class T>void BinaryHeap<T>::Insert(T &data){ if(mCurSize>=mCapacity) { mCapacity*=2; mCurSize++; } m_pData[mCurSize]=data; filterUp(mCurSize);}
完成了最大堆的建立,就可以进行最大元素的抽取了,将抽取的元素存起来,就可以进行迭代过程的排序了:
这里在抽取最大元素的抽取后,相应的元素个数就会减少一个,如果是把根元素的孩子结点移动到根元素的位置,然后从上往下进行这样的移动,这样不能很好的保持完全二叉树的性质。因此这里采取的小技巧是,将二叉树的最后一个元素移动到根元素的位置,这样仅仅只是交换value值,不需要频繁的移动元素的位置。以下是该过程的示意图:
第一步:
第二步:
这样就完成了最大元素的抽取过程了,然后下面是具体的实现过程:
template<class T>T BinaryHeap<T>::delHeap(){ int parentIndex=0; T tempMax=m_pData[parentIndex]; int nIndex=parentIndex*2+1; m_pData[parentIndex]=m_pData[mCurSize-1]; T tempCur=m_pData[parentIndex]; while((nIndex+1)<mCurSize) { if(tempCur>=m_pData[nIndex] && tempCur>=m_pData[nIndex+1]) { break; } else { if(m_pData[nIndex]>m_pData[nIndex+1]) { m_pData[parentIndex]=m_pData[nIndex]; parentIndex=nIndex; } else { m_pData[parentIndex]=m_pData[nIndex+1]; parentIndex=nIndex+1; } nIndex=2*parentIndex+1; } } m_pData[parentIndex]=tempCur; if(mCurSize>1) mCurSize--; else { mCurSize--; cout<<"the heap size is zero!"<<endl; } return tempMax;}
以上就是关键的过程的代码,下面是完整过程的代码:
首先是二叉堆的头文件:
#ifndef BINARYHEAP_H_INCLUDED#define BINARYHEAP_H_INCLUDED#include<vector>#include<queue>#include<iostream>using namespace std;template<class T>class BinaryHeap{public: BinaryHeap(int capacity); ~BinaryHeap(); void filterUp(int start); void Insert(T &data); T delHeap(); void BuildHeap(vector<T> initArray); void displayHeap();private: T *m_pData; int mCurSize; int mCapacity;};template<class T>BinaryHeap<T>::BinaryHeap(int capacity){ mCurSize=0; mCapacity=capacity; m_pData=new T[capacity];}template<class T>BinaryHeap<T>::~BinaryHeap(){ mCurSize=0; mCapacity=0; delete []m_pData;}template<class T>void BinaryHeap<T>::filterUp(int start){ int nIndex=start; T temp=m_pData[nIndex]; int parentIndex=(int) start/2; while(nIndex>0) { if(m_pData[parentIndex]<temp) { m_pData[nIndex]=m_pData[parentIndex]; nIndex=parentIndex; parentIndex=(int) nIndex/2; } else break; } m_pData[nIndex]=temp;}template<class T>void BinaryHeap<T>::Insert(T &data){ if(mCurSize>=mCapacity) { mCapacity*=2; mCurSize++; } m_pData[mCurSize]=data; filterUp(mCurSize);}template<class T>void BinaryHeap<T>::BuildHeap(vector<T> initArray){ int nSize=initArray.size(); if(nSize==0) return; else { for(int i=0;i<nSize;i++) { Insert(initArray.at(i)); if(mCurSize<mCapacity) mCurSize++; else { mCapacity*=2; mCurSize++; } } }}template<class T>T BinaryHeap<T>::delHeap(){ int parentIndex=0; T tempMax=m_pData[parentIndex]; int nIndex=parentIndex*2+1; m_pData[parentIndex]=m_pData[mCurSize-1]; T tempCur=m_pData[parentIndex]; while((nIndex+1)<mCurSize) { if(tempCur>=m_pData[nIndex] && tempCur>=m_pData[nIndex+1]) { break; } else { if(m_pData[nIndex]>m_pData[nIndex+1]) { m_pData[parentIndex]=m_pData[nIndex]; parentIndex=nIndex; } else { m_pData[parentIndex]=m_pData[nIndex+1]; parentIndex=nIndex+1; } nIndex=2*parentIndex+1; } } m_pData[parentIndex]=tempCur; if(mCurSize>1) mCurSize--; else { mCurSize--; cout<<"the heap size is zero!"<<endl; } return tempMax;}template<class T>void BinaryHeap<T>::displayHeap(){ for(int i=0;i<mCurSize;i++) { cout<<m_pData[i]<<"---"; } cout<<endl;}#endif // BINARYHEAP_H_INCLUDED
#include <iostream>#include<cstdlib>#include<ctime>#include"BinaryHeap.h"using namespace std;int main(){ srand(unsigned(time(NULL))); vector<int> initArray; int data=rand()%100; int length=rand()%15; int cnt=0; while(cnt<length) { initArray.push_back(data); data=rand()%100; cnt++; } cout<<"待排序序列:"<<endl; for(int i=0;i<length;i++) cout<<initArray.at(i)<<"---"; cout<<endl; BinaryHeap<int> heap(30); heap.BuildHeap(initArray); cout<<"建立好的最大堆:"<<endl; heap.displayHeap(); int maxEle; vector<int> sortedArray; for(int i=0;i<initArray.size();i++) { maxEle=heap.delHeap(); sortedArray.push_back(maxEle); } cout<<"排序完成的序列:"<<endl; for(int i=0;i<sortedArray.size();i++) { cout<<sortedArray.at(i)<<"---"; } cout<<endl; cout << "Hello world!" << endl; return 0;}
- 数据结构--二叉堆与堆排序
- 数据结构 二叉堆 & 堆排序
- 二叉堆与堆排序
- 二叉堆与堆排序
- 【数据结构】堆与堆排序
- 数据结构之二叉堆、堆排序
- [数据结构] 二叉堆,堆排序,优先级队列
- 数据结构之二叉堆(构建堆,堆排序)-(七)
- 数据结构之二叉堆(构建堆,堆排序)
- 数据结构与算法:堆与堆排序
- 数据结构与算法-堆与堆排序
- 【数据结构与算法】二叉堆
- 【数据结构】二叉堆与左偏树
- 【二叉堆、堆排序】
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 二叉堆 & 堆排序
- 数据结构基础(19) --堆与堆排序
- 【线段树】登山climb
- Javascript
- 1003 pie
- Redhat中安装rsync
- 数组排序
- 数据结构--二叉堆与堆排序
- 转。。。学嵌入式
- 腾讯云服务器完美解决无法使用公网IP访问的问题
- increment/decrement/dereference操作符
- Java的构造方法
- 使用Memcached、Spring AOP构建数据库前端缓存框架
- java字符串的替换replace、replaceAll、replaceFirst的区别详解
- SSH搭建开发环境
- BestCoder Round #81 (div.2)C HDOJ5672 String(双指针法)