【问题标题】:Insert and heapsort to heap built with an array插入并堆排序到用数组构建的堆
【发布时间】:2018-03-22 01:46:23
【问题描述】:

我正在尝试使用数组创建二进制堆。我已经成功地使用buildHeapheapify 建立了堆。我的问题是当我尝试将 insert 一个新元素放入数组时,以及当我尝试使用 heapSort 对其进行排序时。

这是我为 heapify 函数提供的内容:

void heap::Heapify(int arr[], int i){
    int largest = i;
    int L = LeftChild(i);
    int R = RightChild(i);
    if (L <= heapSize && arr[L] > arr[i])
        largest = L;
    else{
        largest = i;
    }

    if (R <= heapSize && arr[R] > arr[largest]){
        largest = R;
    }
    if(largest != i){
        int temp = arr[i];
        arr[i] = arr[largest];
        arr[largest] = temp;
        Heapify(arr, largest);
    }
}

这是我的buildHeap 函数:

void heap::BuildHeap(int arr[]){
    for(int i = (heapSize/2)-1; i >= 0; i--){
        Heapify(arr, i);
    }
}

这两个功能有效,而以下功能无效,对于插入它没有将其插入正确的位置。

这里是insert 函数:

void heap::Insert(int arr[], int key){
    heapSize++;
    int i = heapSize - 1;

    while(i > 0 && arr[Parent(i)] <= key){
        arr[i] = arr[Parent(i)];
        i = Parent(i);
    }

    arr[i] = key;
}

使用heapSort 函数,它在很大程度上对其进行排序,但会像这样打印它(第一行是排序之前的堆):

32 24 5 19 23 4 3 11 2 12 
5 2 4 3 23 19 32 11 24 12 

这是我的heapSort 函数:

void heap::HeapSort(int arr[]){
    for(int i = heapSize - 1; i >= 0; i--){
        int temp = arr[0];
        arr[0] = arr[i];
        arr[i] = temp;

        heapSize = heapSize - 1;
        Heapify(arr, 0);
    }
}

任何帮助确定这两个功能如何无法正常工作的帮助将不胜感激。

【问题讨论】:

  • 看起来像一个简单的调试任务。如果您尝试交换两个值,但交换后两者都相同并且另一个值丢失,那将是不好的。对于正确的minimal reproducible example,我希望将其复制粘贴到我的编译器中并得到与您相同的问题。
  • 你真的应该回顾一下二叉堆背后的理论。序列 32 24 5 19 23 4 3 11 2 12 看起来不像是有效内容。堆排序不会对堆的内部数据进行就地排序,而是逐个提取最小值/最大值。
  • arr[i] = arr[Parent(i)]; 应该是std::swap(arr[i], arr[Parent(i)])

标签: c++ arrays binary-heap


【解决方案1】:

我认为问题在于这些行中的Off-by-One-Error

if (L <= heapSize && arr[L] > arr[i])

if (R <= heapSize && arr[R] > arr[largest]){

它们都应该是&lt; 而不是&lt;=,因为最后一个元素在heapsSize-1 中。

其他细节

void heap::Heapify(int arr[], int i){
    int largest = i; // setting largest to i first time
    int L = LeftChild(i);
    int R = RightChild(i);
    if (L <= heapSize && arr[L] > arr[i]) // compare with arr[i] is not wrong but doesn't express the intent.
        largest = L;
    else{
        largest = i; // setting largest to i second time
    }

    if (R <= heapSize && arr[R] > arr[largest]){
        largest = R;
    }
    if(largest != i){
        int temp = arr[i];      // these 3 lines are the std::swap
        arr[i] = arr[largest];  // or you could roll your own function that does the same.
        arr[largest] = temp;    // better expressing the intent.
        Heapify(arr, largest);
    }
}

改写为

void heap::Heapify(int arr[], int i){
    int largest = i;
    int L = LeftChild(i);
    int R = RightChild(i);

    if (L < heapSize && arr[L] > arr[largest]) {
        largest = L;
     }

    if (R < heapSize && arr[R] > arr[largest]) {
        largest = R;
    }

    if(largest != i){
        swap(arr[i], arr[largest]);
        Heapify(arr, largest);
    }
}

【讨论】:

    猜你喜欢
    • 2018-07-10
    • 2016-12-25
    • 1970-01-01
    • 1970-01-01
    • 2013-04-10
    • 2011-09-01
    • 2018-10-15
    • 2011-07-01
    • 2017-07-21
    相关资源
    最近更新 更多