c++小根堆数组实现
来源:互联网 发布:在线财神网淘宝店 编辑:程序博客网 时间:2024/06/06 11:02
主要功能
最小堆排序(大到小): void order();
删除首元素: Type fetch_root();
插入元素: void insert_item(const Type & item);
void insert_item_faster(const Type & item);
//快速版本
关键
- 向下调整比较关键,即从start结点到end结点逐个调整最小堆:
void shiftdown(Type* array, int start, int end);
另外是实现了迭代版本,效果都是一样的;void shiftdown_regression(Type* array, int start, int end);
- 最小堆调整函数:
int mini_operation(Type* array, int father, int lchild , int rchild);
保证父结点比左右子都小;
source code
/** * @file mini-complete-binary-heap.cpp * @brief * @author anribras@gmail.com * @version * @date 2017-07-04 */#include <string.h>#include <stdio.h>#include <iostream>#include <math.h>#include <stdlib.h>using namespace std;#define min_2(a,b) ((a<b)?(a):(b))#define min_3(a,b,c) min_2(min_2(a,b),min_2(a,c))#define Null (0)/** @brief min_array_heap * * 最小根堆 最大的作用是从huge数据中找到最小的元素 * 也可以排序 * * * */template<typename Type>class min_array_heap { private: int m_size; Type* m_array; void swap(Type & a, Type & b) { Type tmp; tmp = a; a = b; b = tmp; }; //从i节点开始往下调整,调整到第end个节点,序号从0开始 void shiftdown(Type* array, int start, int end) { int lchild = 2* start + 1; int rchild = 2* start + 2; int min; while (lchild <= end) { //cout << "father[" << start << "] = " << array[start] << endl; //cout << "left child[" << lchild << "] = " << array[lchild] << endl; //cout << "right child[" << rchild << "] = " << array[rchild] << endl;#if 0 // 左子 < 父亲 if( array[lchild] < array[start]) { // 如果 右子存在 且 右子 < 左子 if ( (rchild < end) && (array[rchild] < array[lchild]) ) { swap(array[rchild],array[start]); start ++; } else swap(array[lchild],array[start]); } else { // 左子 > 父亲 但是右子 < 父亲 if( (rchild < end) && (array[rchild] < array[start])) { swap(array[rchild],array[start]); start ++; } }#else //如果右子超范围了,只比较左子和父亲 if(rchild >= end) { min = min_2(array[start],array[lchild]); if (min == array[lchild]) { swap(array[lchild],array[start]); } } //否则都要比较 else { min = min_3(array[start],array[lchild],array[rchild]); if( min == array[lchild]) { swap(array[lchild],array[start]); } if (min == array[rchild]) { swap(array[rchild],array[start]); start++; } }#endif start = lchild; lchild = 2* start + 1; rchild = 2* start + 2; } }; //递归版本 void shiftdown_regression(Type* array, int start, int end) { int lchild = 2* start + 1; int rchild = 2* start + 2; if(lchild > end) return; if(rchild == end) { mini_operation(array, start,lchild,rchild); return; } //最后一个无右子,交换左子与父亲即可 if(lchild == end) { mini_operation(array, start,lchild,lchild); return ; } int offset = mini_operation(array,start,lchild, rchild); //offset = 0,从左子开始调整 if (offset == 0) { shiftdown_regression(array,lchild, end); } else { //否则从右子开始调整 shiftdown_regression(array,rchild, end); } } //最小堆操作,将父亲,左子,右子调整好, //返回偏移是该往左(0),还是往右(1) int mini_operation(Type* array, int father, int lchild , int rchild) { int min = min_3(array[father],array[lchild],array[rchild]); if( min == array[lchild]) { swap(array[lchild],array[father]); return 0; } if (min == array[rchild]) { swap(array[rchild],array[father]); return 1; } }; public: min_array_heap(): m_array(0),m_size(0){}; min_array_heap(const Type array[], int size): m_size(size) { //因为要动态扩展数组,用realloc更好 //m_array = new Type[m_size]; m_array = (Type*)malloc(m_size * sizeof(Type)); memcpy(m_array,array,m_size* sizeof(Type)); update(); //update_reg(); }; ~min_array_heap(){ if(m_array) free(m_array); m_size = 0; }; min_array_heap(const min_array_heap & array) { m_size = array.m_size; m_array = new Type[m_size]; memcpy(m_array,array.m_array,m_size* sizeof(Type)); }; min_array_heap & operator=(const min_array_heap & array) { if(this == &array) return *this; delete [] m_array; m_size = array.m_size; m_array = new Type[m_size]; memcpy(m_array,array,m_size* sizeof(Type)); }; const Type & operator[](int pos) { return m_array[pos]; }; int get_size() {return m_size;} Type get_min_node() { return m_array[0]; } //堆初始化 void update() { int n = (m_size - 1); //从最后一个node的父亲往根结点逐个调整 for(int i = (n -1)/2; i >=0; i-- ) shiftdown(m_array,i,n); } void update_reg() { int n = (m_size - 1); //从最后一个node的父亲往根结点逐个调整 for(int i = (n -1)/2; i >=0; i-- ) shiftdown_regression(m_array,i,n); } //从pos往根结点逐个调整 void update(int pos) { int n = pos; for(int i = (n -1)/2; i >=0; i-- ) shiftdown(m_array,i,n); } void insert_item(const Type & item ) { m_size ++; m_array= (Type*)realloc(m_array,m_size*sizeof(Type)); m_array[m_size - 1] = item; update(); }; void insert_item_faster(const Type & item ) { m_size ++; m_array= (Type*)realloc(m_array,m_size*sizeof(Type)); m_array[m_size - 1] = item; //新插入结点到根结点的序列是已排序的, //将新结点重新排序, 其他结点不用动,非常快 int start = m_size - 1; int father = (start -1) /2 ; while(father >= 0) { if(m_array[father] > m_array[start]) swap(m_array[father],m_array[start]); else break; start = father; father = (start -1) /2 ; } }; int fetch_root(Type* item) { if(m_size > 0) { *item = m_array[0]; m_array[0] = m_array[m_size -1]; m_size --; update(); //update_reg(); return 0; } else { return -1; } }; void order() { int start; //小根堆排序 是按从大到小的排序。 //每次将root node和最后一个node交换,最小的node放在最后, //然后重新update从root node到交换node的堆结构 for (start = m_size -1 ; start > 0 ; start --) { swap(m_array[0],m_array[start]); update(start -1); } }; void print_array() { for(int i = 0; i < m_size ; i ++) { cout << m_array[i] << " "; } cout << "\n"; };};/** * @brief main * @param argc * @param argv[] * @return */int main (int argc , char* argv[]){ int size = 10; //int * a = new int[size]; int a[10] = {61, 33, 33, 70, 13, 22, 18, 68, 5, 10 }; srand((int)time(0)); cout << "original:\n"; for(int i =0;i < size; i ++) { //a[i] = rand() % 100; cout << a[i] << " "; } cout << "\n"; cout << "in mini_heap:\n"; min_array_heap<int> mheap(a,size); mheap.print_array(); int tmp; mheap.fetch_root(&tmp); cout << "fetch_root: " << tmp << "\t" << endl; mheap.print_array(); //cout << "normal insert:\n"; //mheap.insert_item(30); //mheap.print_array(); //mheap.fetch_root(); tmp = 10; cout << "faster insert:\n"; mheap.insert_item_faster(tmp); mheap.print_array(); cout << "mini_heap order:\n"; mheap.order(); mheap.print_array(); min_array_heap<int> mheap_t = mheap; //while(mheap_t.get_size()) { //mheap_t.fetch_root(&tmp); //cout << "fetch_root: " << tmp << "\t" << endl; //mheap_t.print_array(); //} //cout << "normal insert:\n"; //mheap.insert_item(30); //mheap.print_array(); //mheap.fetch_root(); //cout << "faster insert:\n"; //mheap.insert_item_faster(10); //mheap.print_array(); cin.get(); //delete [] a; return 0;}
阅读全文
0 0
- 【库】c实现数组
- 【库】c实现数组
- c实现数组归并
- C实现动态数组
- C代码实现数组
- C代码实现数组
- 算法:C实现 数组
- C队列 数组实现
- C代码实现数组
- 数组C语言实现
- 动态数组C语言实现
- C实现动态分配三维数组
- C语言实现动态数组
- 数组的实现---C语言
- 数据结构C语言实现数组
- 动态数组的 C 实现
- C实现数组的基本功能
- C语言数组实现队列
- C语言二维数组行地址与列地址
- NIO
- websocket
- Hadoop 2.4.1伪分布式搭建
- BZOJ 1415聪聪和可可 期望dp
- c++小根堆数组实现
- Python获取目录下的全部文件名,并写入文件中
- hadoop2.4.1集群搭建
- 两个Transformed-前缀的mathematica函数
- SpringMVC 原理详解
- 安装android studio遇到的问题
- 【RMQ】poj 3264 Balanced Lineup
- 获取sd卡某路径下的图片,并展示出来
- 用三元运算符判断奇数和偶数(学习)