1.最小堆实现
来源:互联网 发布:openwrt安装mysql 编辑:程序博客网 时间:2024/05/22 06:53
1.说明
现在开始注重编写一些公共的库,方便自己以后复用,为了提高复用性,采用了模板的方式,同时将这些库发布出来,供大家参考,如有问题或意见请发邮件zhang_int@sina.cn
2.最小堆
至于最小堆的思想,原理等再此就略过吧,结构很简单就不画UML了,简单说明下:
MinHeap.h:最小堆基类,对外部提供接口,方便以后扩展,如采用二叉树形式等
MinHeapArray.h:最小堆的具体实现,采用了数组的形式
Lock.h:线程锁的封装,封装库为ptherad,所以使用线程安全模式时,不支持跨平台
client.cpp:测试用例
现在就直接用代码说话
3.代码实现
//抽象的外部接口和基类 MinHeap.h #ifndef __MINHEAP_H#define __MINHEAP_H#include <string>#include <pthread.h>#include "Lock.h"/**@brief:外部对外抽象的接口,通过接口操作即可*@author:zp*/template <class TYPE>class CMinHeap{public: CMinHeap(){} virtual ~CMinHeap(){} ///@brief:添加元素,采用从上往下移动方式 virtual bool add(const TYPE p) = 0; ///@brief:获取小根堆头结点 ///@ret:0 成功 -1 失败 virtual int front(TYPE& val) = 0; ///@brief:移除头结点元素 ///@ret:0 成功 -1 失败 virtual int pop() = 0; ///@brief:返回堆中元素个数 virtual int size() = 0; ///@brief:获取最后状态错误信息 virtual const std::string& get_lasterror() = 0; private:};#endif//派生类,具体实现MinHeapArray.h#ifndef __MINHEAPARRAY_H#define __MINHEAPARRAY_H#include "MinHeap.h" /************************************************************* @brief: 数组形式的最小堆,通过自动化测试,时间复杂度log(N) @author:zp @atention: 1.如果是自定义复合类型,需要重载 < > = 三个重载运算符,以确定比较方式 2.支持线程安全和非安全模式,所以编译时需链接 lpthread //尚待测试点 函数指针,仿函数,模板函数传进来 //二叉树形式实现没有成功,以后再来把二叉树形式的写了吧**************************************************************/ template <class TYPE>class CMinHeapArray:public CMinHeap<TYPE>{public: CMinHeapArray(const int size, const bool thrdsafe=false); ~CMinHeapArray(); ///@brief:添加元素,采用从上往下移动方式 virtual bool add(const TYPE p); ///@brief:获取小根堆头结点 ///@ret:0 成功 -1 失败 virtual int front(TYPE& val); ///@brief:移除头结点元素 ///@ret:0 成功 -1 失败 virtual int pop(); ///@brief:返回堆中元素个数 virtual int size(); ///@brief:获取最后状态错误信息 virtual const std::string& get_lasterror();private: ///小根堆元素保存的缓冲区 TYPE* m_heap; ///最小堆元素个数限制 int m_size; ///当前元素个数 int m_cur; ///最后状态错误原因 std::string m_lasterror; ///是否支持线程安全 true 支持 fales不支持 bool m_thrdsafe; ///线程安全锁 CLock m_lock; }; template<class TYPE>CMinHeapArray<TYPE>::CMinHeapArray(const int size, const bool thrdsafe){ if (size <= 0) { m_lasterror = "min-heap size illegal"; } else { m_heap = new(std::nothrow) TYPE[size]; if (NULL == m_heap) { m_lasterror = "min-heap init error"; } m_size = size; m_cur = 0; } m_thrdsafe = thrdsafe;}template<class TYPE>CMinHeapArray<TYPE>::~CMinHeapArray(){ delete m_heap; m_heap = NULL;}template <class TYPE> inline const std::string& CMinHeapArray<TYPE>::get_lasterror(){ if (m_thrdsafe) m_lock.lock(); std::string& lasterror = m_lasterror; if (m_thrdsafe) m_lock.unlock(); return m_lasterror;}//bool add(const TYPE p, bool (*compare)(const TYPE a, const TYPE b)=NULL)template <class TYPE> bool CMinHeapArray<TYPE>::add(const TYPE p){ if (m_thrdsafe) m_lock.lock(); int s; s = m_cur; int parent; bool bflag = false; if (m_cur < m_size) { while (s > 0) { parent = (s - 1) / 2; if (m_heap[parent] < p) break; m_heap[s] = m_heap[parent]; s = parent; } m_heap[s] = p; m_cur++; bflag = true; } if (m_thrdsafe) m_lock.unlock(); return bflag;} template <class TYPE>int CMinHeapArray<TYPE>::front(TYPE& val){ if (m_thrdsafe) m_lock.lock(); int flag = -1; if (m_cur > 0) { flag = 0; val = m_heap[0]; } if (m_thrdsafe) m_lock.unlock(); return flag;}///note:在弹出元素时,会将最后元素移动到被移走的空位处template <class TYPE>int CMinHeapArray<TYPE>::pop(){ if (m_thrdsafe) m_lock.lock(); int nret = -1; int s = 0; int half = 0; int smallerpos = 0; if (m_cur > 0) { nret = 0; m_cur--; half = m_cur / 2; while (s < half) { int childl = s*2+1; int childr = s*2+2; smallerpos = childl; if (childr < m_cur && m_heap[childl]>m_heap[childr]) smallerpos = childr; if (m_heap[m_cur]<m_heap[smallerpos]) break; m_heap[s] = m_heap[smallerpos]; s = smallerpos; } m_heap[s] = m_heap[m_cur]; } if (m_thrdsafe) m_lock.unlock(); return nret;} template<class TYPE>inline int CMinHeapArray<TYPE>::size(){ int size = 0; if (m_thrdsafe) m_lock.lock(); m_size = m_cur; if (m_thrdsafe) m_lock.unlock(); return m_cur;} #endif//线程锁封装#ifndef __LOCK_H#define __LOCK_H #include <pthread.h>/****************************************************************@brief:linux平台线程锁*@author:zp*/class CLock{public: CLock() { _lock = new pthread_mutex_t; pthread_mutex_init(_lock, NULL); } ~CLock() { pthread_mutex_destroy(_lock); delete _lock; } void lock() { pthread_mutex_lock(_lock); } void unlock() { pthread_mutex_unlock(_lock); } int trylock_mutex() { return pthread_mutex_trylock(_lock); } private: pthread_mutex_t* _lock;} ;#endif//测试用例#include <iostream>#include <stdlib.h>#include <time.h>/**@brief:最小堆测试和使用用例*@attention:1.自定义复合结构需要重写 < > = 运算符 ,如有必要可以改成回调函数形式* 2.在使用过程中如有逻辑问题或性能问题,请邮件zhang_int@sina.cn**/#include "MinHeap.h"#include "MinHeapArray.h"#define VAL_RANGE 20000#define ARR_SIZE 9999//自定义复合结构测试用例typedef struct SMyStruct{ std::string t1; std::string t2; int a; int b; bool operator < (SMyStruct val) { bool bret = false; if (t1<val.t1) bret = true; return bret; } bool operator > (SMyStruct val) { bool bret = false; if (t1>val.t1) bret = true; return bret; } bool operator = (SMyStruct val) { t1 = val.t1; t2 = val.t2; a = val.a; b = val.b; }} TMyStruct;bool judge(int front, int next){ bool bflag = true; if (front > next) { bflag = false; } return bflag;} //批量自动化测试,随机构造数组大小,随机构造数组内的元素,然后放入到最小堆里面//然后将数据弹出,查看是否是 升序//保证最小堆能够可靠完整的运行 int batch_test(){ //构建自动化测试,保证代码可靠运行 int arrsize; while (1) { int* val; arrsize = random() % ARR_SIZE; if (arrsize == 0) continue; CMinHeap<int>* heap = new CMinHeapArray<int>(arrsize); val = new int[arrsize]; for (int j=0; j<arrsize; j++) { int rand = random() % VAL_RANGE; heap->add(rand); val[j] = rand; } int size = heap->size(); int last; int next; bool bflag = true; for (int i=0; i<size; i++) { if (i==0) { if (heap->front(last) == -1) std::cout<<"front error last."<<std::endl; } else { if (heap->front(next) == -1) std::cout<<"front error next."<<std::endl; if (!judge(last, next)) { bflag = false; } last = next; } //std::cout<<last<<" "; heap->pop(); } if (bflag == false) { std::cout<<"judge error."<<std::endl; for (int i=0; i<arrsize; i++) { std::cout<<val[i]<<" "; } std::cout<<std::endl; std::cin.get(); } std::cout<<"test over "<<arrsize<< "!!!"<<std::endl; usleep(1000); delete heap; heap = NULL; delete val; val = NULL; } return 0;} /*bool compare_min(TMyStruct a, TMyStruct b){ bool bret = false; if (a.t1 < b.t1) bret = true; if (a.t1 == b.t1) std::cout<<"equal."<<std::endl; return bret;}*/void type_test(void){ TMyStruct b[10]; b[0].t1 = "nihao"; b[1].t1 = "test"; b[2].t1 = "1"; b[3].t1 = "god"; b[4].t1 = "msg"; b[5].t1 = "hehe"; b[6].t1 = "yumy"; b[7].t1 = "info"; b[8].t1 = "book"; b[9].t1 = "tea"; CMinHeap<TMyStruct>* heap = new CMinHeapArray<TMyStruct>(10, false); for (int i=0; i<10; i++) { heap->add(b[i]); } int size = heap->size(); TMyStruct t; for (int i=0; i<size; i++) { heap->front(t); std::cout<<t.t1.c_str()<<" "<<std::endl; heap->pop(); } std::cin.get(); } int main(void){ type_test(); batch_test(); return 0;}
0 0
- 1.最小堆实现
- 最小堆的实现
- 最小堆的实现
- 最小堆的实现
- Dijkstra+最小堆实现
- 数组实现最小堆
- Java最小堆实现
- 最小堆实现
- 最小堆&&最大堆的实现(c++)
- 最小堆&&最大堆的实现(c++)
- 最小堆与最大堆的实现
- 数据结构二叉堆C++实现 最小堆
- 最小堆&&最大堆的实现(c++)
- 手工实现堆(最小堆)
- 最大堆与最小堆的实现
- 最大堆、最小堆C++实现
- 最小优先队列--堆实现
- 最小堆的C++实现
- 黑马程序员--Foundation框架NSArray遍历
- webView地址拼接
- 思维的惯性
- openssl之BIO系列之1---抽象的IO接口
- Android 笔记之 application在AndroidManifest中得属性
- 1.最小堆实现
- ios应用,64位问题,Missing 64-bit support
- 日语学习之沪江N3基础 20150626 -4
- opensslBIO系列之2---BIO结构和BIO相关文件介绍
- gre报名考试的流程是什么?
- Android消息队列模型
- openCV之头文件分析
- JVM 运行原理
- BIO系列之3---BIO的声明和释放等基本操作