Cod sursa(job #2452946)

Utilizator 1234554321WDgSzYNDwv 1234554321 Data 1 septembrie 2019 20:29:14
Problema Heapuri Scor 0
Compilator c-64 Status done
Runda Arhiva educationala Marime 4.71 kb
#include<stdio.h>
#include<stdlib.h>

const int INF = 1000000100;
const int MAXN = 2000000;

typedef struct HEAP HEAPSHADOW;
struct HEAP{
    int size;
    int counter;
    size_t elem_size;
    void* elements;
    int* location;
    int* reverselocation;
    char (*compare)( void* , void*);
    void (*swap)( HEAPSHADOW*, int, int );

    void (*push_up)( HEAPSHADOW*, int);
    void (*push_down)( HEAPSHADOW*, int);
    void (*insert_element)( HEAPSHADOW*, void*);
    void (*delete_nth_inserted)( HEAPSHADOW*, int);
    void* (*top)( HEAPSHADOW* );
};
typedef struct HEAP HEAP;

void* top( HEAP* this ){
    return &((int*)this->elements)[0];
}
char compare( void* a, void* b ){
    int inta = *( (int*) a), intb = *( (int*) b);
    return (inta > intb ? 1 : 0);
}
void swap( HEAP* this, int a, int b ){
    int c = ((int*)this->elements)[a];
    ((int*)this->elements)[a] = ((int*)this->elements)[b];
    ((int*)this->elements)[b] = c;
    c = this->location[ this->reverselocation[a] ];
    this->location[ this->reverselocation[a] ] = this->location[ this->reverselocation[b] ];
    this->location[ this->reverselocation[b] ] = c;
    c = this->reverselocation[a];
    this->reverselocation[a] = this->reverselocation[b];
    this->reverselocation[b] = c;

}

void push_up( HEAP* this, int pos ){
    int dad = pos / 2;
    while( dad > 0 && this->compare( &((int*)this->elements)[dad - 1], &((int*)this->elements)[pos - 1] ) ){
        this->swap(this,  dad - 1, pos - 1 );
        pos = dad;
        dad = pos / 2;
    }
}
void push_down( HEAP* this, int pos ){
    char flag = 1;
    int son1, son2;
    while( flag ){
        son1 = pos * 2;
        son2 = pos * 2 + 1;
        if( son1 <= this->size && son2 <= this->size )
            if( ((int*)this->elements)[ pos - 1 ] < ((int*)this->elements)[ son1 - 1 ] && ((int*)this->elements)[ pos - 1 ] < ((int*)this->elements)[ son2 - 1 ] )
                flag = 0;
            else
                if( ((int*)this->elements)[ son1 - 1 ] < ((int*)this->elements)[ son2 - 1 ] ){
                    this->swap( this, pos - 1, son1 - 1 );
                    pos = son1;
                }
                else{
                    this->swap( this, pos - 1, son2 - 1 );
                    pos = son2;
                }
        else
            if( son1 <= this->size)
                if( ((int*)this->elements)[ pos - 1 ] > ((int*)this->elements)[ son1 - 1 ] ){
                    this->swap( this, pos - 1, son1 - 1 );
                    pos = son1;
                }
                else
                    flag = 0;
            else
                flag = 0;
    }
}
void insert_element( HEAP* this, void* elem_void ){
    ((int*)this->elements)[this->size] = *( (int*) elem_void );
    this->location[ this->counter ] = this->size ;
    this->reverselocation[ this->size ] = this->counter;
    this->counter++;
    this->size++;
    this->push_up( this, this->size );
}
void delete_nth_element( HEAP* this, int which ){
    which--;
    int send_down_index = this->location[ which ] + 1;
    this->swap( this, this->location[which], this->size - 1 );
    this->size--;
    ((int*)this->elements)[ this->size ] = -INF;
    if( send_down_index < this->size + 1)
        this->push_down( this, send_down_index );
}

void init( int N, HEAP** h ){
    int* a;
    int i;
    *h = (HEAP* ) malloc( sizeof( HEAP ) );
    (*h)->size = 0;
    (*h)->counter = 0;

    a = (int*) malloc( sizeof( int ) * N );
    (*h)->elements = a;
    for( i = 0; i < N; i++ )
        ((int*)(*h)->elements)[i] = -INF;
    a = (int*) malloc( sizeof( int ) * N );
    (*h)->location = a;
    a = (int*) malloc( sizeof( int ) * N);
    (*h)->reverselocation = a;

    (*h)->top = &top;
    (*h)->compare = &compare;
    (*h)->swap = &swap;
    (*h)->push_up = &push_up;
    (*h)->push_down = &push_down;
    (*h)->insert_element = &insert_element;
    (*h)->delete_nth_inserted = &delete_nth_element;

}

int main(){
    HEAP *my_heap;
    int N, val, i, instr;
    FILE *in, *out;
    in = fopen( "heap.in", "r" );
    out = fopen( "heap.out", "w" );
    fscanf(in, "%d", &N);
    init( N, &my_heap );

    for( i = 0; i < N; i++){
        fscanf( in, "%d", &instr );
        switch( instr ){
            case 1: {
                fscanf( in, "%d", &val );
                my_heap->insert_element( my_heap, &val );
            } break;
            case 2: {
                fscanf( in, "%d", &val );
                my_heap->delete_nth_inserted( my_heap, val );
            }break;
            case 3: {
                fprintf( out, "%d\n", *( (int*) my_heap->top( my_heap ) ) );
            }
        }
    }

    return 0;
}