您的位置:首页 > 理论基础 > 数据结构算法

数据结构--大小堆

2016-08-05 10:39 1341 查看
如果有一个关键码的集合K = {k0,k1, k2,…,kn-1},把它的所有元素按完全二叉树 的顺序存储方式存储在一个一维数组中,并满足:Ki <= K2*i+1 且 Ki<= K2*i+2  (Ki >= K2*i+1 且 Ki >= K2*i+2) i = 0,1,2…,则称这个堆为最小堆(或最大堆)。

最大堆和最小堆是二叉堆的两种形式。

最大堆:根结点的键值是所有堆结点键值中最大者,且每个结点的值都比其孩子的值大。

最小堆:根结点的键值是所有堆结点键值中最小者,且每个结点的值都比其孩子的值小。



这样我们就能根据图大小堆的规则构建大小堆了

我们根据数组arr 最终要创建这样一个树



下面图示流程是 创建 最小堆的过程 :









其实看懂了上面的流程,最小堆的代码也就出来了。

下面把 最大堆的代码就直接放在这了,当然还有一些操作,如:插入、删除、堆顶元素之类的 

#include<iostream>
#include<vector>
#include<assert.h>
using namespace std;

//Use a vector create Heap
template <class T >
class HeapGeater
{
public:
HeapGeater()
{}
HeapGeater(const T arr[], size_t size) //size is Elem_count
{
assert(arr);
//push data
_heap.resize(size);
for (size_t index = 0; index < size; index++)
{
//_heap.push_back(arr[index]);
_heap[index] = arr[index];
}
size_t Root = size / 2 - 1; // the last Leef_Node of Root
for (int index = Root; index >= 0; index--)
{
_AdjustDown(index);
}
}
bool Empty()
{
return _heap.empty();
}
size_t Size()
{
return _heap.size();
}

T& Top()const
{
assert(!Empty());
return _heap[0];
}
const T&Top()
{
assert(!Empty());
return _heap[0];
}

void Insert(const T& data)
{
assert(!Empty());
T tmp = _heap[Size() - 1];
_heap.push_back(data);
if (data > tmp)
{
int Root = Size() / 2 - 1; // the last Leef_Node of Root
for (int index = Root ; index > 0; index--)
{
AdjustUp(index);
}
}
}

void Remove(const T& data)
{
assert(!Empty());
_heap[0] = _heap[Size() - 1];
_heap.resize(Size()-1 );

int Root = Size() / 2 - 1; // the last Leef_Node of Root
for (int index = Root; index >= 0; index--)
{
_AdjustDown(index);
}
}

protected:
void _AdjustDown(size_t Root)//adjust to Max_heap
{
size_t Child = Root * 2 + 1;// find the LeftChild
while (Child < _heap.size())
{
// find Max between left_elem and right_elem
if ((Child + 1 < _heap.size()) && _heap[Child + 1] > _heap[Child])
{
//std::swap(_heap[Child + 1], _heap[Child]);
Child = Child + 1;
}
//confirm The root is MAx
if (_heap[Child] > _heap[Root])
{
std::swap(_heap[Child], _heap[Root]);
Root = Child;
Child = Child*2 + 1;
}
else
{
break;
}
}//end while
}
void AdjustUp(int Root)
{
int child = Size() - 1; //Find the inserted data
while ( Root >= 0 && _heap[Root] < _heap[child])
{
swap(_heap[Root], _heap[child]);
child = Root;
Root = (Root - 1) / 2;
}
}
private:
std::vector<T> _heap;
};

/********Test Code**********/
void test_heapGeater()
{
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
HeapGeater<int> ap(arr,8);
cout <<"****************" << endl;

cout<< ap.Size()<<endl;
ap.Insert(99);
cout << ap.Top() << endl;
cout << ap.Size() << endl;
ap.Remove(8);
cout << ap.Top() << endl;
cout << ap.Size() << endl;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: