To_review_100_0---堆的整理

    引入:

    一些按照重要性或优先级来组织的对象称为优先队列。

    在普通队列数据结构中查找具有最高优先级元素的时间代价为O(n),因而普通队列不能有效地实现优先队列。

    在有序表或无序表中插入和删除的时间代价都是O(n)。

    可以考虑使用把记录按优先级组织的BST,其平均情况下插入和删除操作的总时间代价为O(nlogn),平均时间代价为O(logn)。但是BST可能会变得不平衡,这将导致BST性能变得很差。(若是完全二叉树就很好)

    堆可以解决上述问题。


    关于堆:

    1. 它是一棵完全二叉树,常用数组来实现。

    2. 对中存储的数据是局部有序的,包括最大堆和最小堆(无论最小堆还是最大堆,任何一个结点与其兄弟结点之间都没有必然联系)


    堆元素父节点与子节点映射于数组的关系:

    1. 父节点下标为i,则左子节点为2i+1,右子节点为2i+2。

    2. 子节点小标为i,则父节点为i-1/2。

    2. 叶子节点下标大于等于数组长度/2。


    性能分析:

    1. 建堆 O(n),远比建立BST的平均时间复杂度O(nlogn)和最差时间复杂度O(n*n)要好得多。

    2. 删除对优先级最高的元素O(logn)


    C++实现代码:

#include <iostream>
#include <string>
using namespace std;


// Heap class
template <class E> class heap{
private:
 E* Heap;    // Pointer to the heap array
 int maxsize;   // Maximum size of the heap
 int n;     // Number of elements now in the heap


 bool Prior(E x, E y){
  return x > y;
 }

 void swap(E* source, int x, int y){
  E temp = source[x];
  source[x] = source[y];
  source[y] = temp;
 }

 void Assert(bool test, string error){
  if (!test){
   cout << error << endl;
   exit(1);
  }
 }

 // Helper function to put element in its correct place
 void siftdown(int pos){
  while (!isLeaf(pos)){ // Stop if pos is a leaf
   int j = leftchild(pos);
   int rc = rightchild(pos);
   if ((rc < n) && Prior(Heap[rc], Heap[j]))
    j = rc;   // Set j to greater child's value
   if (Prior(Heap[pos], Heap[j]))  
    return;   //Done
   swap(Heap, pos, j);
   pos = j;   //Move down
  }
 }

public:
 heap(E* h, int num, int max) // Constructor
 {
  Heap = h;
  n = num;
  maxsize = max;
  buildHeap();
 }
 int size() const{
  return n;
 }
 bool isLeaf(int pos) const{
  return (pos >= n / 2) && (pos < n);
 }
 int leftchild(int pos) const{
  return pos * 2 + 1;
 }
 int rightchild(int pos) const{
  return pos * 2 + 2;
 }
 int parent(int pos) const{
  return (pos - 1) / 2;
 }
 void buildHeap(){     //从暂时的堆的最底层父节点开始往上层调整
  for (int i = n / 2 - 1; i >= 0; i--)
   siftdown(i);
 }

 // Insert "it" into the heap
 void insert(const E& it){
  Assert(n < maxsize, "Heap is full");
  int cur = n++;
  Heap[curr] = it;    // Start at end of heap
  // Now sift up until curr's parnt>curr
  while ((curr != 0) && (Prior(Heap[curr], Heap[parent(curr)]))){ //只跟踪插入元素进行追踪调整
   swap(Heap, curr, parent(curr));
   curr = parent(curr);
  }
 }

 // Remove first value
 E removefirst(){
  Assert(n > 0, "Heap is empty");
  swap(Heap, 0, --n);
  if (n != 0)
   siftdown(0);     // Siftdown new root val
  return Heap[n];      // Return deleted value 
 }

 // Remove and return element at specified position
 E remove(int pos){
  Assert((pos >= 0) && (pos < n), "Bad position");
  if (pos == (n - 1))
   n--; // Last element, no work to do
  else{
   swap(Heap, pos, --n);  //Swap with last value
   while ((pos != 0) && (Prior(Heap[pos], Heap[parent(pos)]))){  // Push up large key
    swap(Heap, pos, parent(pos));
    pos = parent(pos);
   }
   if (n != 0)
    siftdown(pos);              // Push down small key
  }
  return Heap[n];
 }
};

int main(){
 int source[7] = { 7, 4, 6, 1, 2, 3, 5 };
 heap<int> test(source, 7, 100);
 cout << test.removefirst() << endl;
 cout << test.removefirst() << endl;
 cout << test.removefirst() << endl;
 cout << test.removefirst() << endl;
 return 0;
}

   

    感觉别人写得好多了=_=,附上网址:http://blog.csdn.net/morewindows/article/details/6709644/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值