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

发布于 2024-12-28 11:49:40 字数 1292 浏览 5 评论 0 原文

我正在阅读有关堆数据结构的内容,但我不知道何时使用 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);
      }
    }
  }

i'm reading about the heap data structure, and i can't figure out when to use max heapify function and why.

I wrote a insert function that will always keep the heap a max-heap and i can't see when will max-heapify ever be used.

Can you please explain?
Thank you

this is my code:

  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);
      }
    }
  }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏九 2025-01-04 11:49:40

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

The heapify algorithm should be used when turning an array into a heap. You could do that by inserting each array element in turn into a new heap, but that would take O(n lg n) time, while heapify does it in O(n) time.

标点 2025-01-04 11:49:40

max_heapify 预计会在常规数组上调用,以使其成为堆。 insert 负责维护工作,这需要数组(函数中的v)已经是一个堆。

max_heapify is expected to invoke on a regular array, to make it a heap. And insert does the maintenance work, which requires the array (v in your function) already being a heap.

轮廓§ 2025-01-04 11:49:40

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

处理堆的函数的复杂性(及其预期用途):

  • init (max-heapify):O(n) ,使用从排序序列(数组)(最大排序,在您的情况下)初始化堆
  • insert : O(lg n) ,使用在堆中插入单个元素(维护堆树“排序”)
  • delete : O(lg n) ,用于从堆中删除“最佳”(在您的情况下是最大)元素(维护堆树“排序”)

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

std::set 的唯一问题是它是一个唯一的容器 - 这意味着其中只能存在具有相同键的元素的 1 个副本。但也有一个解决方案 - std::multiset 使用相同的键保留多个对象的排序实例。

另外,根据您所需的使用情况(如果有大量与搜索键关联的数据),您可能还想尝试 std::mapstd::multimap

如果您想实现自己的堆实现,并且您的目的是充分使用 C++,我强烈建议您将其放入单独的类(甚至命名空间)中。如果您只想保持实现的原样,您应该考虑将问题重新标记为 C

The max-heapify function, as you call it, is a general heapify function (a heap can use any valid comparison function for sorting it's elements). It is intended to be used as an init function for constructing a heap from an array.

The complexities of functions for dealing with a heap (with their intented usages):

  • init (max-heapify): O(n) , used to initialize a heap from a sorted sequence (array) (max-sorted, in your case)
  • insert : O(lg n) , used to insert a single element in a heap (maintains the heap tree "sorted")
  • delete : O(lg n) , used to remove a "best" (max, in your case) element from a heap (maintains the heap tree "sorted")

But, since this question is tagged C++, you should also consider using a std::set from STL instead of implementing your own heap. Complexities of the considered operations are the same as for any heap implementation, and it can easily operate with any comparison function (either pre-written or user-written). Another advantage against a heap implementation is that it is a sorted container, and you can easily iterate trough all the elements in the sorted order (not just the first one) without destroying the structure.

The only problem with std::set is that it is a unique container - meaning, only 1 copy of an element with a same key can exist in it. But there is a solution for that also - std::multiset keeps sorted instances of multiple objects with the same key.

Also, depending on your required usage (it there is a lot of data associated with the search key), you might also want to try std::map or std::multimap.

If you want to make your own heap implementation, I would strongly suggest putting it in a separate class (or even a namespace) if your intention is to use C++ to the fullest. If you just intend to keep the implementation in the form it is, you should consider re-tagging the question to C

被翻牌 2025-01-04 11:49:40

您需要像数组一样将数据随机插入堆中。之后你可以调用 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);
            }
        }
    }

You need to insert the data in heap randomly like in array. Afterwards u can call the max heapify function to keep the property of a Max Heap. Here is my code

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);
            }
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文