实现基于数组,这里使用的不定长数组。
编号从1开始,当然从数组0位开始也可以。
为了验证代码的可靠性,在main方法上方编写了测试器
(基于模版类)
插入
得到最小值
删除(根)
层序输出
theta(n)复杂度的建树操作:
循环更新堆
删除指定节点
这里其实就是把插入和删除操作合并在一起了。
作为最小堆,如果更新的数值比之前小只需要与父亲们比较即可->不断上浮
如果更新的数值比之前大,只需要与大孩子不断比较->不断下沉。
template
void minheap::fresh(T target, T changer) {
if (size == 0)
return;
for (int i = size; i >= 1; --i)
{ if (con[i] == target)
{ con[i] = con[i] + changer;
if (changer < 0) //如果变小一定往上移动
{
int lastnode = i;
T lastelement = con[i];
while (lastnode > 1 && con[lastnode / 2] > lastelement) {
//注意不能取1
con[lastnode] = con[lastnode / 2];
lastnode /= 2;
}
con[lastnode] = lastelement;
}
if (changer > 0) //如果变大就与孩子交换
{
T lastelement = con[i];
int temp = i;
int child = i * 2;
while (child <= size) {
if (child + 1 <= size && con[child + 1] < con[child])
child++;
if (con[child] >= con[temp])
break;
con[temp] = con[child];
temp = child;
child *= 2;
}
con[temp] = lastelement;
}
}
}
}
template <class T>
void minheap::initialize(vector v) {
if (v.size() == 0)
return;
for (int i = 0; i < v.size(); ++i)
{
if (i == 0)
con.push_back(v[i]);
con.push_back(v[i]);
}
this->size = v.size();
//下面进行调整
int tem = size / 2;
T lastelement = con[tem];
int child = tem * 2;
while (tem >= 1) {
while (child <= size) {
if (child + 1 <= size && con[child + 1] < con[child])
child++;
if (lastelement < con[child])
break;
con[child / 2] = con[child];
child *= 2;
}
con[child / 2] = lastelement;
tem--;
child = tem * 2;
lastelement = con[tem];
}
}
void tester(minheap<int> & con,int num) {
srand((int)time(0));
vector<int> vec;
for (int x = 0; x < num; x++) {
int a = random(100);
con.push(a);
vec.push_back(a);
sort(vec.begin(), vec.end());
printf("data:%d\n", a);
}
for (int i = 0; i < num; ++i)
cout << "quickly sort: " << vec[i] << endl;
cout << "--" << endl;
int counter = 0;
while (!con.empty())
{
if (con.top() == vec[counter])
cout << con.top() << "--" << vec[counter++]<<" yes"<else{
cout <<"算法存在错误!"<break;
}
con.pop();
}
}
#include
#include
#include
#include
#define random(x) (rand()%x) //测试用代码
using namespace std;
template <class T>
class minheap
{
public:
minheap();
~minheap();
void pop();
T top();
void push(T element);
int getsize() {
return this->size;
}
void fresh(T target, T changer);
void initialize(vector v);
bool empty() {
return size == 0;
}
void level_show();
vector con; //从1开始使用不用0
private: //直接使用T本身作为优先级
int size;
void swap(T &a , T &b);
};
template<class T>
minheap::minheap() {
con.clear();
size = 0;
}
template <class T>
void minheap::fresh(T target, T changer) {
if (size == 0)
return;
for (int i = size; i >= 1; --i)
{ if (con[i] == target)
{ con[i] = con[i] + changer;
if (changer < 0) //如果变小一定往上移动
{
int lastnode = i;
T lastelement = con[i];
while (lastnode > 1 && con[lastnode / 2] > lastelement) {
//注意不能取1
con[lastnode] = con[lastnode / 2];
lastnode /= 2;
}
con[lastnode] = lastelement;
}
if (changer > 0) //如果变大就与孩子交换
{
T lastelement = con[i];
int temp = i;
int child = i * 2;
while (child <= size) {
if (child + 1 <= size && con[child + 1] < con[child])
child++;
if (con[child] >= con[temp])
break;
con[temp] = con[child];
temp = child;
child *= 2;
}
con[temp] = lastelement;
}
}
}
}
template <class T>
T minheap:: top() {
if (size == 0)
return 0;
else
return con[1];
}
template <class T>
void minheap::pop() {
if (size == 0)
return;
if (size == 1)
{
size = 0;
return;
}
T lastelement = con[size];
size--;
int currentnode = 1;
int child = 2;
while (child <= size) {
if (child + 1 <= size && con[child] > con[child + 1])
child++; //首先找到大孩子
if (lastelement <= con[child])
break;
con[currentnode] = con[child];
currentnode = child;
child *= 2;
}
con[child / 2] = lastelement;
}
template<class T>
minheap::~minheap() {
con.clear();
size = 0;
}
template <class T>
void minheap::initialize(vector v) {
if (v.size() == 0)
return;
for (int i = 0; i < v.size(); ++i)
{
if (i == 0)
con.push_back(v[i]);
con.push_back(v[i]);
}
this->size = v.size();
//下面进行调整
int tem = size / 2;
T lastelement = con[tem];
int child = tem * 2;
while (tem >= 1) {
while (child <= size) {
if (child + 1 <= size && con[child + 1] < con[child])
child++;
if (lastelement < con[child])
break;
con[child / 2] = con[child];
child *= 2;
}
con[child / 2] = lastelement;
tem--;
child = tem * 2;
lastelement = con[tem];
}
}
template <class T>
void minheap::swap(T& a , T &b) {
T c = a;
a = b;
b = c;
}
template <class T>
void minheap::push(T element) {
if (size == 0)
{
size = 1;
con.push_back(element);//因为我们不使用0位,我们从1位开始使用
con.push_back(element);//当然从0开始也是可以的
return;
}
con.push_back(element);
int pos = ++size;
while (pos > 1) {
if (element < con[pos / 2] )
swap(con[pos], con[pos / 2]);
pos /= 2;
}
}
template <class T>
void minheap::level_show() {
if (con.empty())
return;
if (size == 1)
{
cout << con[1] << endl;
return;
}
queue<int> t;
t.push(1);
int temp;
while (!t.empty())
{
temp = t.front();
cout << con[temp] << " " ;
t.pop();
if (2 * temp <= size) //看左孩子
t.push(2 * temp);
if (2 * temp + 1 <= size) //看右孩子
t.push(2 * temp + 1);
}
cout << endl;
}
void tester(minheap<int> & con, int num) {
srand((int)time(0));
vector<int> vec;
for (int x = 0; x < num; x++) {
int a = x;
// con.push(a);
vec.push_back(a);
printf("data:%d\n", a);
}
con.initialize(vec); //使用初始化进行排序
cout << con.getsize() << endl;
sort(vec.begin(), vec.end());
for (int i = 0; i < num; ++i)
cout << "quickly sort: " << vec[i] << endl;
cout << "--" << endl;
int counter = 0;
while (!con.empty())
{
if (con.top() == vec[counter])
cout << con.top() << "--" << vec[counter++] << " yes" << endl;
else {
cout << "算法存在错误!" << endl;
break;
}
con.pop();
}
}
int main(int argc, char const * argv[])
{
minheap<int> mmp;
tester(mmp,10);
return 0;
}