《github一天,一个算术题》:堆算法接口(堆排序、堆插入和堆垛机最大的价值,并删除)
阅览、认为、编写代码!
/*********************************************
* copyright@hustyangju
* blog: http://blog.csdn.net/hustyangju
* 题目:堆排序实现,另外实现接口:取堆最大值并删除、堆插入
* 思路:堆是在顺序数组原址上实现的。利用全然二叉树的性质。更具最大堆和最小堆的定义实现的。
* 经典应用场景:内存中堆数据管理
* 空间复杂度:堆排序是在原址上实现的,为0
* 时间复杂度:堆排序为O(n lgn) ,取最值O(1)。插入最坏为O(lgn)
*********************************************/
#include <iostream>
#include <algorithm> using namespace::std; //对堆排序实现类的定义
class HeapSort
{
public:
HeapSort(int *pArray , int nArraySize);//constructor
~HeapSort();//destructor
private:
int *m_pA;//points to an array
int m_nHeapSize;//stands for the size
public:
void BuildMaxHeap(); //build a heap
void Sort();//建一个最大堆并排序。依照顺序(由小到大)放在原数组
int PopMaxHeap();//取最大堆的最大值
void InsertMaxHeap(int a);//插入一个新值到最大堆,事实上就是在元素尾部增加一个值,再维护最大堆的性质
void print();//顺序输出数组
protected:
int LeftChild(int node);//取左孩子下标
int RightChild(int node);//取右孩子下标
int Parent(int node);//取父节点下标
void MaxHeapify(int nIndex);//justify the heap
}; //构造函数初始化
HeapSort::HeapSort( int *pArray, int nArraySize )
{
m_pA = pArray;
m_nHeapSize = nArraySize;
} //析构函数
HeapSort::~HeapSort()
{
} //取左孩子下标。注意沿袭数组从0開始的习惯
int HeapSort::LeftChild(int node)
{
return 2*node + 1;// the array starts from 0
} //取右孩子下标
int HeapSort::RightChild(int node)
{
return 2*node + 2;
} //取父节点下标
int HeapSort::Parent(int node)
{
return (node-1)/2 ;
} //利用递归维护最大堆的性质。前提是已经建好最大堆。仅仅对变动的结点调用该函数
void HeapSort::MaxHeapify(int nIndex)
{
int nLeft = LeftChild(nIndex);
int nRight = RightChild(nIndex); int nLargest = nIndex; if( (nLeft < m_nHeapSize) && (m_pA[nLeft] > m_pA[nIndex]) )
nLargest = nLeft; if( (nRight < m_nHeapSize) && (m_pA[nRight] > m_pA[nLargest]) )
nLargest = nRight; if ( nLargest != nIndex )//假设有结点变动才继续递归
{
swap<int>(m_pA[nIndex], m_pA[nLargest]);
MaxHeapify(nLargest);
}
} //建造最大堆,思路:对于一个全然二叉树,子数组A[int((n-1)/2)+1]~A[n-1]为叶子结点
//A[0]~A[int((n-1)/2)]为非叶子结点。从下到上,从最后一个非叶子结点開始维护最大堆的性质
void HeapSort::BuildMaxHeap()
{
if( m_pA == NULL )
return; for( int i = (m_nHeapSize - 1)/2; i >= 0; i-- )
{
MaxHeapify(i);
}
} //不断取最大堆的最大值A[0]与最后一个元素交换,将最大值放在数组后面。顺序排列数组
void HeapSort::Sort()
{
if( m_pA == NULL )
return;
if( m_nHeapSize == 0 )
return;
for( int i = m_nHeapSize - 1; i > 0; i-- )
{
swap<int>(m_pA[i], m_pA[0]);
m_nHeapSize -= 1;//这个表达式具有破坏性!! !
MaxHeapify(0);
}
} //取出最大值,并在堆中删除
int HeapSort::PopMaxHeap()
{
/*if( m_pA == NULL )
return ;
if( m_nHeapSize == 0 )
return ;*/
int a= m_pA[0];
m_pA[0]=m_pA[m_nHeapSize-1];
m_nHeapSize -= 1;
MaxHeapify(0);
return a;
} //插入一个值。思路:放在数组最后面(符合数组插入常识),再逐层回溯维护最大堆的性质
void HeapSort::InsertMaxHeap(int a)
{
/*
if( m_pA == NULL )
return;
if( m_nHeapSize == 0 )
return;
*/
m_nHeapSize += 1;
m_pA[m_nHeapSize-1]=a;
int index=m_nHeapSize-1;
while(index>0)
{
if(m_pA[index]>m_pA[Parent(index)])
{
swap(m_pA[index], m_pA[Parent(index)]);
index=Parent(index);
}
else
index=0;//注意这里。某一层已经满足最大堆的性质了,就不须要再回溯了
}
} //顺序输出数组
void HeapSort::print()
{
for(int i=0;i<m_nHeapSize;i++)
cout<<m_pA[i]<<" ";
cout<<endl;
}
int main()
{
int a[10]={6,5,9,8,1,0,3,2,7,4};
//int max;
cout<<"input an array::"<<endl;
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
HeapSort myHeap(a,10);
myHeap.BuildMaxHeap();
cout<<"pop the max number:"<<endl;
cout<<"the max="<<myHeap.PopMaxHeap()<<endl;
cout<<"after pop:"<<endl;
myHeap.print();
myHeap.InsertMaxHeap(11);
cout<<"insert a number and sort:"<<endl;
myHeap.Sort();
// myHeap.print();
for(int i=0;i<10;i++)
cout<<a[i]<<" ";
cout<<endl;
}
測试结果:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvaHVzdHlhbmdqdQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" alt="">
版权声明:本文博主原创文章。博客,未经同意,不得转载。
《github一天,一个算术题》:堆算法接口(堆排序、堆插入和堆垛机最大的价值,并删除)的更多相关文章
- ZeroMQ接口函数之 :zmq_z85_decode – 从一个用Z85算法生成的文本中解析出二进制密码
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_z85_decode zmq_z85_decode(3) ØMQ Manual - ØMQ/4.1 ...
- Python3实现最小堆建堆算法
今天看Python CookBook中关于“求list中最大(最小)的N个元素”的内容,介绍了直接使用python的heapq模块的nlargest和nsmallest函数的解决方式,记得学习数据结构 ...
- 自己写算法---java的堆的非递归遍历
import java.io.*; import java.util.*; public class Main { public static void main(String args[]) { S ...
- C++算法接口使用参考
C++算法接口参考 算法参考:[algorithm] 编译:g++ -std=c++11 xxx_algorithm.cpp 运行:./a.out 1.保持原序列运算 all_of template ...
- C# 最大二叉堆算法
C#练习二叉堆算法. namespace 算法 { /// <summary> /// 最大堆 /// </summary> /// <typeparam name=&q ...
- 论C++STL源代码中关于堆算法的那些事
关于堆,我们肯定熟知的就是它排序的时间复杂度在几个排序算法里面算是比較靠上的O(nlogn)常常会拿来和高速排序和归并排序讨论,并且它还有个长处是它的空间复杂度为O(1), 可是STL中没有给我们提供 ...
- 《排序算法》——堆排序(大顶堆,小顶堆,Java)
十大算法之堆排序: 堆的定义例如以下: n个元素的序列{k0,k1,...,ki,-,k(n-1)}当且仅当满足下关系时,称之为堆. " ki<=k2i,ki<=k2i+1;或k ...
- java数据结构和算法10(堆)
这篇我们说说堆这种数据结构,其实到这里就暂时把java的数据结构告一段落,感觉说的也差不多了,各种常见的数据结构都说到了,其实还有一种数据结构是“图”,然而暂时对图没啥兴趣,等有兴趣的再说:还有排序算 ...
- SmartSql使用教程(1)——初探,建立一个简单的CURD接口服务
一.引言 最近SmartSql被正式引入到了NCC,借着这个契机写一个使用教程系列 二.SmartSql简介[摘自官方文档] 1. SmartSql是什么? SmartSql = MyBatis + ...
随机推荐
- python学习笔记之九:模块和包
Python的标准安装包括一组模块,称为标准库.这里介绍模块的工作方式,学习如何使用它们. 一. 模块 1.1 用import从外部模块获取函数并为自己的程序所用: >>> from ...
- Android DES加密的CBC模式加密解密和ECB模式加密解密
DES加密共有四种模式:电子密码本模式(ECB).加密分组链接模式(CBC).加密反馈模式(CFB)和输出反馈模式(OFB). CBC模式加密: import java.security.Key; i ...
- 飘逸的python - 发送带各种类型附件的邮件
上一篇博文演示了如何发送简单的邮件,这一篇将演示如何发送各种类型的附件. 基本思路就是,使用MIMEMultipart来标示这个邮件是多个部分组成的,然后attach各个部分.如果是附件,则add_h ...
- 三层架构与MVC
三层简介 先说说Web三层架构这个古老话题.地球人都知道web三层架构是指: • >用户接口层(UI Layer) • >业务逻辑层(Bussiness Layer) • >持久化层 ...
- mysql copy复制拷贝表数据及结构的几种方式(转)
mysql拷贝表操作我们会常常用到,下面就为您详细介绍几种mysql拷贝表的方式,希望对您学习mysql拷贝表方面能够有所帮助.假如我们有以下这样一个表:id username password--- ...
- java大全经典的书面采访
果学网 -专注IT在线www.prismcollege.com 1.面向对象的特征有哪些方面 1.抽象: 抽象就是忽略一个主题中与当前目标无关的那些方面.以便更充分地注意与当前目标有关的方面.抽象并 ...
- [Ext.Net]GridPanel之Access数据库分页显示
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.D ...
- 基于KMP与Levenshtein模糊匹配算法的银行联行号查询(转)
在人民银行那里,每个银行的每一个营业网点都有自己唯一的银行联行号,根据这个号码能快速定位一间银行具体的分支行,就像根据一个身份证号码能快速确定一个人一样.例如汇款时,汇款单上要求填写收款人开户行,然后 ...
- Eclipse+Maven创建webapp项目<二> (转)
Eclipse+Maven创建webapp项目<二> 1.开启eclipse,右键new——>other,如下图找到maven project 2.选择maven project,显 ...
- BZOJ 1150 CTSC2007 数据备份Backup 堆+馋
标题效果:给定一个长度n−1n-1的序列,要求选出kk个不相邻的数使得和最小 费用流显然能跑.并且显然过不去- - 考虑用堆模拟费用流 一个错误的贪心是每次取最小.这样显然过不去例子 我们把[每次取最 ...