Heap-006-Index-Heap

本文介绍了一种利用索引最大堆进行堆排序的方法,通过定义IndexMaxHeap类,实现了元素插入、删除最大元素等功能。并在主函数中演示了如何使用此方法对大量随机数据进行排序,最后通过SortTestHelper测试排序算法的有效性。

main.cpp

#include <iostream>
#include <cassert>
#include "SortTestHelper.h"

#define Priority int

using namespace std;

template<typename Item>
class IndexMaxHeap{

private:
    Item *data;
    int *indexes;

    int count;
    int capacity;

    void shiftUp( int k ){

        while( k > 1 && data[indexes[k/2]] < data[indexes[k]] ){
            swap( indexes[k/2] , indexes[k] );
            k /= 2;
        }
    }

    void shiftDown( int k ){

        while( 2*k <= count ){
            int j = 2*k;
            if( j + 1 <= count && data[indexes[j+1]] > data[indexes[j]] )
                j += 1;

            if( data[indexes[k]] >= data[indexes[j]] )
                break;

            swap( indexes[k] , indexes[j] );
            k = j;
        }
    }

public:
    IndexMaxHeap(int capacity){

        data = new Item[capacity+1];
        indexes = new int[capacity+1];

        count = 0;
        this->capacity = capacity;
    }

    ~IndexMaxHeap(){
        delete[] data;
        delete[] indexes;
    }

    int size(){
        return count;
    }

    bool isEmpty(){
        return count == 0;
    }

    // 传入的i对用户而言,是从0索引的
    void insert(int i, Item item){
        assert( count + 1 <= capacity );
        assert( i + 1 >= 1 && i + 1 <= capacity );

        i += 1;
        data[i] = item;
        indexes[count+1] = i;
        count++;

        shiftUp(count);
    }

    Item extractMax(){
        assert( count > 0 );

        Item ret = data[indexes[1]];
        swap( indexes[1] , indexes[count] );
        count--;
        shiftDown(1);
        return ret;
    }

    int extractMaxIndex(){
        assert( count > 0 );

        int ret = indexes[1] - 1;
        swap( indexes[1] , indexes[count] );
        count--;
        shiftDown(1);
        return ret;
    }

    Item getMax(){
        assert( count > 0 );
        return data[indexes[1]];
    }

    int getMaxIndex(){
        assert( count > 0 );
        return indexes[1]-1;
    }

    Item getItem( int i ){
        return data[i+1];
    }

    void change( int i , Item newItem ){

        i += 1;
        data[i] = newItem;

        // 找到indexes[j] = i, j表示data[i]在堆中的位置
        // 之后shiftUp(j), 再shiftDown(j)

        for( int j = 1 ; j <= count ; j ++ )
            if( indexes[j] == i ){
                shiftUp(j);
                shiftDown(j);
                return;
            }
    }

    // test reverse index
    bool testReverseIndex(){

        int *copyIndexes = new int[count+1];

        for( int i = 0 ; i <= count ; i ++ ){
            copyIndexes[i] = indexes[i];
        }

        copyIndexes[0] = 0;
        std::sort(copyIndexes, copyIndexes + count + 1);

        bool res = true;
        for( int i = 1 ; i <= count ; i ++ )
            if( copyIndexes[i-1] + 1 != copyIndexes[i] )
                res = res || false;

        delete[] copyIndexes;

        if( !res ){
            cout<<"Error 1"<<endl;
            return res;
        }

        return true;
    }
};

template<typename T>
void heapSortUsingIndexMaxHeap(T arr[], int n){

    IndexMaxHeap<T> indexMaxHeap = IndexMaxHeap<T>(n);
    for( int i = 0 ; i < n ; i ++ )
        indexMaxHeap.insert( i , arr[i] );
    assert( indexMaxHeap.testReverseIndex() );

    for( int i = n-1 ; i >= 0 ; i -- )
        arr[i] = indexMaxHeap.extractMax();
}

int main() {

    int n = 1000000;

    Priority* arr = new Priority[n];
    srand(time(NULL));
    for( int i = 0 ; i < n ; i ++ )
        arr[i] = rand()%n;
    SortTestHelper::testSort("Heap Sort Using Index-Max-Heap", heapSortUsingIndexMaxHeap, arr, n);
    delete[] arr;

    return 0;
}
#include <stdio.h> #include <stdlib.h> // 最小堆结构体 typedef struct { int *data; int size; int capacity; } MinHeap; // 交换两个整数 void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } // 初始化最小堆 MinHeap* initHeap(int capacity) { MinHeap *heap = (MinHeap*)malloc(sizeof(MinHeap)); heap->data = (int*)malloc(capacity * sizeof(int)); heap->size = 0; heap->capacity = capacity; return heap; } // 上滤操作 void siftUp(MinHeap *heap, int index) { while (index > 0 && heap->data[index] < heap->data[(index - 1) / 2]) { swap(&heap->data[index], &heap->data[(index - 1) / 2]); index = (index - 1) / 2; } } // 插入元素到最小堆 void insert(MinHeap *heap, int value) { if (heap->size < heap->capacity) { heap->data[heap->size] = value; siftUp(heap, heap->size++); } } // 下滤操作 void siftDown(MinHeap *heap, int index) { int left, right, smallest; while (1) { left = 2 * index + 1; right = 2 * index + 2; smallest = index; if (left < heap->size && heap->data[left] < heap->data[smallest]) smallest = left; if (right < heap->size && heap->data[right] < heap->data[smallest]) smallest = right; if (smallest == index) break; swap(&heap->data[index], &heap->data[smallest]); index = smallest; } } // 提取最小元素 int extractMin(MinHeap *heap) { if (heap->size == 0) return -1; int min = heap->data[0]; heap->data[0] = heap->data[--heap->size]; siftDown(heap, 0); return min; } // 销毁最小堆 void destroyHeap(MinHeap *heap) { free(heap->data); free(heap); } int main() { MinHeap *heap = initHeap(10); insert(heap, 3); insert(heap, 1); insert(heap, 2); printf("Extracted Min: %d\n", extractMin(heap)); printf("Extracted Min: %d\n", extractMin(heap)); destroyHeap(heap); return 0; }帮我简洁优化一下
11-27
#include <stdio.h> #include <stdlib.h> // 最小堆结构体 typedef struct MinHeap { int* data; // 存储堆元素的数组 int size; // 当前堆的大小 int capacity;// 堆的最大容量 } MinHeap; // 初始化最小堆 MinHeap* createMinHeap(int capacity) { MinHeap* heap = (MinHeap*)malloc(sizeof(MinHeap)); heap->capacity = capacity; heap->size = 0; heap->data = (int*)malloc((capacity + 1) * sizeof(int)); // 1-based索引 return heap; } // 交换两个整数 void swap(int* a, int* b) { int temp = *a; *a = *b; *b = temp; } // 向上调整堆(插入元素时) void heapifyUp(MinHeap* heap, int index) { while (index > 1 && heap->data[index] < heap->data[index / 2]) { swap(&heap->data[index], &heap->data[index / 2]); index /= 2; } } // 向下调整堆(删除元素时) void heapifyDown(MinHeap* heap, int index) { int smallest = index; int left = 2 * index; int right = 2 * index + 1; if (left <= heap->size && heap->data[left] < heap->data[smallest]) smallest = left; if (right <= heap->size && heap->data[right] < heap->data[smallest]) smallest = right; if (smallest != index) { swap(&heap->data[index], &heap->data[smallest]); heapifyDown(heap, smallest); } } // 插入元素到堆 void insert(MinHeap* heap, int value) { if (heap->size >= heap->capacity) { // 扩容(可选,本题数据量固定,可省略) heap->capacity *= 2; heap->data = (int*)realloc(heap->data, (heap->capacity + 1) * sizeof(int)); } heap->data[++heap->size] = value; heapifyUp(heap, heap->size); } // 提取堆顶最小元素 int extractMin(MinHeap* heap) { if (heap->size == 0) return -1; // 空堆 int min = heap->data[1]; heap->data[1] = heap->data[heap->size--]; heapifyDown(heap, 1); return min; } // 销毁堆 void destroyMinHeap(MinHeap* heap) { free(heap->data); free(heap); } int main() { int n; scanf("%d", &n); MinHeap* heap = createMinHeap(n); for (int i = 0; i < n; i++) { int num; scanf("%d", &num); insert(heap, num); } int total体力 = 0; while (heap->size > 1) { // 提取两个最小元素 int a = extractMin(heap); int b = extractMin(heap); // 合并 int sum = a + b; total体力 += sum; // 插入合并后的元素 insert(heap, sum); } printf("%d\n", total体力); destroyMinHeap(heap); return 0; }帮我简洁优化一下
11-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值