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

To_review_100_0---堆的整理

2015-06-11 13:28 387 查看
    引入:

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

    在普通队列数据结构中查找具有最高优先级元素的时间代价为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
;      // 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
;

 }

};

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/


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数据结构 算法