二进制堆 - 如何以及何时使用max-heapify

时间:2012-01-21 16:22:18

标签: c++ data-structures heap max-heap

我正在阅读堆数据结构,我无法弄清楚何时使用max heapify函数及其原因。

我编写了一个插入函数,它将始终使堆保持最大堆,并且我无法看到何时使用max-heapify。

你可以解释一下吗? 谢谢

这是我的代码:

    int  PARENT(int i)
    {
return i/2;
    }

    int LEFT(int i)
    {
return 2*i;
    }
    int RIGHT(int i )
   {
return 2*i +1;
   }


    void max_heapify(int *v, int index, int heapsize)
    {
int largest;
    int left = LEFT(index);
int right = RIGHT(index);
if (left<heapsize && v[left] > v[index])
    largest = left;
else 
    largest = index;
if (right < heapsize && v[right] > v[largest])
    largest = right;
if (largest !=index)
{
    v[index]  = v[index] ^v[largest];
    v[largest] = v[index] ^v[largest];
    v[index] = v[index] ^v[largest];
    max_heapify(v,largest,heapsize);
}

    }

    void insert(int *v, int * length, int value)
    {
v[++*length] = value;
int valuePos = *length;
int parent = PARENT(valuePos);
if (parent!=valuePos)
{
    while (v[parent] < v[valuePos])
    {
        v[parent] = v[parent] ^ v[valuePos];
        v[valuePos] = v[parent] ^v[valuePos];
        v[parent] = v[parent] ^ v[valuePos];
        valuePos = parent;
        parent = PARENT(valuePos);
    }
}

}

4 个答案:

答案 0 :(得分:1)

将数组转换为堆时,应使用heapify算法。您可以通过将每个数组元素依次插入到新堆中来实现,但这需要O( n lg n )时间,而heapify在O(< em> n )时间。

答案 1 :(得分:0)

max_heapify应该在常规数组上调用,以使其成为堆。并且insert执行维护工作,这需要数组(函数中的v)已经是堆。

答案 2 :(得分:0)

max-heapify函数,就像你所说的那样,是一个通用heapify函数(一个堆可以使用任何有效的比较函数来对它的元素进行排序)。它旨在用作init函数,用于从数组构造堆。

处理堆的函数的复杂性(以及它们的用法):

  • init max-heapify ):O( n ),用于从排序序列初始化堆( array)(最大排序,在你的情况下)
  • insert:O(lg n ),用于在堆中插入单个元素(维护堆树“已排序”)
  • delete:O(lg n ),用于从堆中删除“最佳”(在您的情况下为max)元素(维护堆树“已排序”)< / LI>

但是,由于此问题已标记为C++,因此您还应考虑使用STL中的std::set而不是实现自己的堆。所考虑的操作的复杂性与任何堆实现相同,并且可以使用任何比较功能(预编写或用户编写)轻松操作。针对堆实现的另一个优点是它是一个已排序的容器,您可以轻松地迭代排序顺序中的所有元素(而不仅仅是第一个),而不会破坏结构。

std::set的唯一问题是它是一个唯一的容器 - 意味着,只有一个具有相同密钥的元素的副本可以存在于其中。但是也有一个解决方案 - std::multiset使用相同的密钥保持多个对象的已排序实例。

此外,根据您的使用要求(与搜索键相关的数据很多),您可能还想尝试std::mapstd::multimap

如果你想创建自己的堆实现,如果你的目的是充分利用C++,我强烈建议把它放在一个单独的类(甚至命名空间)中。如果您打算以实际形式保留实施,则应考虑将问题重新标记为C

答案 3 :(得分:0)

您需要在数组中随机插入数据。之后你可以调用max heapify函数来保持Max Heap的属性。这是我的代码

class max_heap{  
 private:               // are the private members of class
      int *arr;
      int size;
      int ind;
};

        void max_heap::bubbledown(int *ar, int i)
        {
         int len = ind - 1;
         int lt = 2 * i;
         int rt = lt + 1;
         while (lt <= len && rt <= len)                                         
         {
            if (arr[i] > arr[lt] && arr[i] > arr[rt])
                break;

            else if (ar[lt] > ar[rt])
            {
                if (ar[i] < ar[lt]){
                    swap(ar[i], ar[lt]);
                    i = lt;
                    lt = 2 * i;
                }
            }
            else if (ar[lt] < ar[rt])
            {
                if (ar[i] < ar[rt]){
                    swap(ar[i], ar[rt]);
                    i = rt;
                    rt = (2 * i)+1;
                }
            }
        }
    }

    void max_heap::heapify()
    {
        int len = ind - 1;
        for (int i = len; i >= 1 && (i/2) >= 1; i--)
        {
            if (arr[i] > arr[i/2])
            {
                swap(arr[i], arr[i/2]);
                bubbledown(arr, i);
            }
        }
    }