大小堆的实现,删除,添加

来源:互联网 发布:java选择题及答案 编辑:程序博客网 时间:2024/06/06 09:58

大小堆的实现   删除   添加

最小堆:任一结点的关键码均小于等于它的左右孩子的关键码,位于堆顶结点的关键码最小 
最大堆:任一结点的关键码均大于等于它的左右孩子的关键码,位于堆顶结点的关键码 最大

先建堆:利用二叉树建小堆方法

先找到第一个非叶子节点,然后检查它是否有左右叶子(都有选其小的),再和节点比较,若小于该节点,则交换这两个元素;接着把这个节点当作叶子,找他的节点,再按上述方法做;
相关代码:
#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;

template<typename T>
class HEAP
{
public:
void Adtreesort(T* arr, int size)
{
assert(arr);
for (int i = 0; i < size; ++i)
{
Heap.push_back(arr[i]);
}
int root = (size - 1) / 2;
while (root--)
{
AdtreeDown(root);
}
}


//堆添加
void insert(T data)
{
Heap.push_back(data);
int root = (Heap.size() - 1) / 2;
int temp = Heap.size() - 1;
while (temp>root)
{
if (Heap[temp] < Heap[root])
{
std::swap(Heap[Heap.size() - 1], Heap[root]);
temp = root;
root = (root - 1) / 2;
}
else
{
return;
}
}
}


//堆删除
void Erase()
{
swap(Heap[0],Heap[Heap.size()-1]);
Heap.pop_back();
AdtreeDown(0);
}


//打印
void Print()
{
for (size_t i = 0; i < Heap.size(); ++i)
{
cout << Heap[i] << "->";
}
cout << endl;
}
private:
void AdtreeDown(int root) //调整节点
{
int left = root * 2 + 1;  
int right = left + 1;
int Min = left;
while (left<Heap.size())
{
if (Heap[left] > Heap[right])
{
Min = right;
}
if (Heap[root] > Heap[Min])
{
swap(Heap[root], Heap[Min]);
root = Min;
left = root * 2 + 1;
right = left + 1;
Min = left;
}
else
{
break;
}
}
}
private:
vector<T> Heap;
};

调试代码:
void Fun()
{
int arr[] = { 1, 5, 6, 3, 4, 7, 9, 8, 0 };
HEAP<int> h;
h.Adtreesort(arr,9);
h.insert(2);
h.Print();
h.Erase();
h.Print();
}

int main()
{
Fun();
system("pause");
return 0;
}
0 0