码迷,mamicode.com
首页 > 其他好文 > 详细

【数据结构】堆heap

时间:2015-05-11 22:04:11      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

     本节研究堆heap的相关操作实现;


说明几点

(1)堆分为大根堆和小根堆;大根堆的根为最大值,每一个节点的值都不小于其孩子的值;

(2)可以利用大根堆实现升序排序;主要是利用大根堆的头和需要排序的最后一个数字交换的思想;

(3)使用大根堆实现最大优先级队列,类似stl中queue的操作,只是对于元素在队列中的元素优先级是不一样的,在最大优先级中,队列头为值最大元素;可利用大根堆来维护一个最大优先级队列;向优先级队列中push元素,类似像堆的末尾添加一个元素,然后使用_makeHeapUp寻找该元素的存放位置,进而维护大根堆;当向优先级队列中pop元素,将首元素和最后一个元素对换,然后使用_makeHeapDown来从首元素向下维护大根堆,类似堆排序,最后再将尾部元素pop_back;

(4)stl中使用sort_heap对容器进行堆排序,注意该容器需保证已经符合堆的特性

(5)stl中使用make_heap对对一个容器中的值进行建堆;pop_heap,push_heap分别对队进行出堆(出堆之后,出堆值保存在容器的尾部)和入堆(入堆之前,入堆值已经保存在容器的尾部);


堆排序

inline int left(int parent)
{
  return parent*2 + 1;
}

inline int right(int parent)
{
  return parent*2 + 2;
}

inline int parent(int child)
{
  return (child-1) / 2;
}

void _makeHeapDown(vector<int>& array, int top, int end)
{
  while (left(top) < end)
    {
      int leftChild = left(top);
      int rightChild = right(top);

      int min = top;
      if (array[top] < array[leftChild])
        min = leftChild;

      if (rightChild < end && array[min] < array[rightChild])
        min = rightChild;

      if (top == min)
        break;

      swap(array[min], array[top]);

      top = min;
    }
}

void heapSort(vector<int>& array)
{
  for (int i = array.size() / 2; i >= 0; --i)
    _makeHeapDown(array, i, array.size());

  for (int i = array.size()-1; i >= 1; --i)
    {
      swap(array[i], array[0]);
      _makeHeapDown(array, 0, i);
    }
}

说明几点:

(1)在堆排序中,仅仅使用了向下维护堆特性,但是优先级队列中使用了向上和向下维护堆特性;


优先级队列

inline int left(int parent)
{
  return parent*2 + 1;
}

inline int right(int parent)
{
  return parent*2 + 2;
}

inline int parent(int child)
{
  return (child-1) / 2;
}

void _makeHeapDown(vector<int>& array, int top, int end)
{
  while (left(top) < end)
    {
      int leftChild = left(top);
      int rightChild = right(top);

      int min = top;
      if (array[top] < array[leftChild])
        min = leftChild;

      if (rightChild < end && array[min] < array[rightChild])
        min = rightChild;

      if (top == min)
        break;

      swap(array[min], array[top]);

      top = min;
    }
}

void _makeHeapUp(vector<int>& array, int last)
{
  if (last < 0)
    return;

  int value = array[last];
  while (last > 0)
    {
      int parentIndex = parent(last);

      if (array[parentIndex] < value)
        {
          array[last] = array[parentIndex];
          last = parentIndex;
        }
      else
        {
          break;
        }
    }

  array[last] = value;
}

class PriorityQueue
{
public:
  int size() const
  {
    return _seq.size();
  }

  bool empty() const
  {
    return _seq.empty();
  }

  void push(int x)
  {
    _seq.push_back(x);
    _makeHeapUp(_seq, _seq.size()-1);
  }

  int top()
  {
    if (_seq.empty())
      return -1;

    return _seq[0];
  }

  void pop()
  {
    if (_seq.empty())
      return;

    swap(_seq[0], _seq[_seq.size()-1]);
    _makeHeapDown(_seq, 0, _seq.size()-1);

    _seq.pop_back();
  }

private:
  vector<int> _seq;
};



【数据结构】堆heap

标签:

原文地址:http://blog.csdn.net/skyuppour/article/details/45647983

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!