堆用C ++排序

时间:2011-09-22 19:13:09

标签: c++ sorting data-structures

好的,所以在努力调试之后,我终于放弃了。我是C ++的初学者和数据结构,我正在尝试用C ++实现堆排序。下面的代码给出了正整数的正确输出,但是当我尝试输入一些负整数时似乎失败了。

请在以下代码中指出任何错误/差异。此外,我们将很高兴收到有关该主题的任何其他建议/批评。

//Heap Sort
#include <iostream.h>
#include <conio.h>
int a[50],n,hs;
void swap(int &x,int &y)
{
    int temp=x;
    x=y;
    y=temp;
}
void heapify(int x)
{
    int left=(2*x);
    int right=(2*x)+1;
    int large;
    if((left<=hs)&&(a[left]>a[x]))
    {
        large=left;
    }
    else
    {
        large=x;
    }
    if((right<=hs)&&(a[right]>a[large]))
    {
        large=right;
    }
    if(x!=large)
    {
        swap(a[x],a[large]);
        heapify(large);
    }
}
void BuildMaxHeap()
{
    for(int i=n/2;i>0;i--)
    {
        heapify(i);
    }
}
void HeapSort()
{
    BuildMaxHeap();
    hs=n;
    for(int i=hs;i>1;i--)
    {
        swap(a[1],a[i]);
        hs--;
        heapify(1);
    }
}
void main()
{
    int i;
    clrscr();
    cout<<"Enter length:\t";
    cin>>n;
    cout<<endl<<"Enter elements:\n";
    for(i=1;i<=n;i++)       //Read Array
    {
        cin>>a[i];
    }
    HeapSort();
    cout<<endl<<"Sorted elements:\n";
    for(i=1;i<=n;i++)       //Print Sorted Array
    {
        cout<<a[i];
        if(i!=n)
        {
            cout<<"\t";
        }
    }
    getch();
}

我一直在阅读Heap Sort,但我无法掌握大部分概念,如果没有这个,我就无法解决上面的逻辑错误。

5 个答案:

答案 0 :(得分:6)

在致电hs后设置BuildMaxHeap。切换这两行。

hs=n;
BuildMaxHeap();

答案 1 :(得分:1)

当我实施自己的heapsort时,我必须格外注意指数;如果从0开始索引,则子项为2x + 1和2x + 2,当您从1开始索引时,子项为2x和2x + 1。因此,有很多无声的问题。此外,每个操作都需要一个编写良好的siftDown函数,这是至关重要的。

在Heapsort和Binary堆文章中打开Wikipedia,并尝试在可能的情况下按照术语和符号更干净地重写它。 Here is my implementation,也许它可以提供帮助。

嗯,现在我更好地检查了你的代码,你确定你的siftDown / heapify函数限制了筛选到当前堆的大小吗?

编辑:发现问题!在调用BuildMaxHeap()之前,您不会将hs初始化为n

答案 2 :(得分:0)

我怀疑这是因为你是以阵列为基础的。可能有一种情况,你不小心将它作为基础,但我无法在代码中发现它。

答案 3 :(得分:0)

如果有帮助的话,这是一个例子。

#include <iostream>
#include <vector>

using namespace std;

void max_heapify(std::vector<int>& arr, int index, int N) {
    // get the left and right index
    int left_index = 2*index + 1;
    int right_index = 2*index + 2;

    int largest = 0;
    if (left_index < N && arr[left_index] > arr[index]) {
        // the value at the left_index is larger than the 
        // value at the index of the array
        largest = left_index;
    } else {
        largest = index;
    }

    if (right_index < N && arr[right_index] > arr[largest]) {
        // the value at the right_index is larger than the
        // value at the index of the array
        largest = right_index;
    }

    // check if largest is still the index, if not swap
    if (index != largest) {
        // swap the value at index with value at largest
        int temp = arr[largest];
        arr[largest] = arr[index];
        arr[index] = temp;

        // once swap is done, do max_heapify on the index
        max_heapify(arr, largest, N);
    }
}

void build_max_heap(std::vector<int>& arr, int N) {
    // select all the non-leaf except the root and max_heapify them
    for (int i = N/2 - 1; i >= 0; --i) {
        max_heapify(arr, i, N);
    }
}

void heap_sort(std::vector<int>& arr) {
    int N = arr.size();
    int heap_size = N;
    // build the max heap
    build_max_heap(arr, N);

    // once max heap is built,
    // to sort swap the value at root and last index
    for (int i = N - 1; i > 0; --i) {
        // swap the elements
        int root = arr[0];
        arr[0] = arr[i];
        arr[i] = root;

        // remove the last node
        --heap_size;

        // perform max_heapify on updated heap with the index of the root
        max_heapify(arr, 0, heap_size);
    }
}

int main() {
    std::vector<int> data = {5,1,8,3,4,9,10};

    // create max heap from the array
    heap_sort(data);

    for (int i : data) {
        cout << i << " ";
    }

    return 0;
}

答案 4 :(得分:0)

# include <iostream>   //Desouky//
 using namespace std;

void reheapify(int *arr, int n, int i)
{
int parent = i; // initilaize largest as parent/root
int child1 = 2 * i + 1; // to get first chid 
int child2 = 2 * i + 2; // to get second child

if (child1 < n && arr[child1] > arr[parent]) // if child2 >  parent
{
    parent = child1;
}
//if child > the parent 
if (child2 < n && arr[child2] > arr[parent])
{
    parent = child2;
}
// if the largest  not the parent 
if (parent != i)
{
    swap(arr[i], arr[parent]);
    // Recursively heapify the affected sub-tree
    reheapify(arr, n, parent);
}

}
 void heapsort(int *arr, int n)
 {
 // build a heap
for (int i = n - 1; i >= 0; i--)
{
    reheapify(arr, n, i);
}
// One by one extract an element from heap
for (int i = n - 1; i >= 0; i--)
{
    // Move current root to end
    swap(arr[0], arr[i]);

    // call max heapify on the reduced heap
    reheapify(arr, i, 0);
 }
 }

 int main()
 {

freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
cin >> n;
int* arr = new int[n];
for (int i = 0; i < n; i++)
{
    cin >> arr[i];
}
heapsort(arr, n);
for (int i = 0; i < n; i++)
{
    cout << arr[i] << " ";
}

 }