Cod sursa(job #2669042)

Utilizator GrandmasterSoucup Bogdan Grandmaster Data 5 noiembrie 2020 22:25:26
Problema Sortare prin comparare Scor 80
Compilator c-32 Status done
Runda Arhiva educationala Marime 3.58 kb
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

#define INITIAL_CAPACITY (1<<20)

struct PQueue_t {
  double *heap;
  int32_t *indexes;
  int32_t size;
};

typedef struct PQueue_t *PQueue;

PQueue pq_New(void) {
  PQueue queue = malloc(sizeof(struct PQueue_t));
  queue->heap = malloc(sizeof(double) * INITIAL_CAPACITY);
  queue->indexes = malloc(sizeof(int32_t) * INITIAL_CAPACITY);
  queue->size = 0;
  return queue;
}

void fswap(double *array, int32_t a, int32_t b) {
  double aux = array[a];
  array[a] = array[b];
  array[b] = aux;
}

void swap(int32_t *array, int32_t a, int32_t b) {
  int32_t aux = array[a];
  array[a] = array[b];
  array[b] = aux;
}

void pushElement(PQueue queue, int32_t index) {
    if(!index) {
        return ;
    }
    if(!(index & 1)) {
        if(queue->heap[index] <= queue->heap[(index - 1) >> 1]) {
            fswap(queue->heap, index, (index - 1) >> 1);
            swap(queue->indexes, index, (index - 1) >> 1);
            pushElement(queue, (index - 1) >> 1);
        }
    }
    else {
        if(queue->heap[index] <= queue->heap[index >> 1]) {
            fswap(queue->heap, index, index >> 1);
            swap(queue->indexes, index, index >> 1);
            pushElement(queue, index >> 1);
        }
    }
}

void pq_Push(PQueue queue, double value, int32_t index) {
  queue->heap[queue->size] = value;
  queue->indexes[queue->size] = index;
  pushElement(queue, queue->size);
  queue->size++;
}

void pq_DeleteHead(PQueue queue) {
  double *heap = queue->heap;
  int32_t *indexes = queue->indexes;
  int32_t heapSize = queue->size;
  int32_t index = 0;
  fswap(heap, 0, heapSize - 1);
  swap(indexes, 0, heapSize - 1);
  queue->size--;
  heapSize--;
  while(((index << 1) + 1 < heapSize && heap[index] > heap[(index << 1) + 1]) ||
        ((index << 1) + 2 < heapSize && heap[index] > heap[(index << 1) + 2])) {
    if((index << 1) + 2 >= heapSize) {
      fswap(heap, index, (index << 1) + 1);
      swap(indexes, index, (index << 1) + 1);
      index <<= 1;
      index++;
    }
    else if(heap[(index << 1) + 2] >= heap[(index << 1) + 1]) {
      fswap(heap, index, (index << 1) + 1);
      swap(indexes, index, (index << 1) + 1);
      index <<= 1;
      index++;
    }
    else {
      fswap(heap, index, (index << 1) + 2);
      swap(indexes, index, (index << 1) + 2);
      index <<= 1;
      index += 2;
    }
  }
}

int32_t pq_GetMinValueIndex(PQueue queue) {
  if(!queue->size)
    return -1;
  return queue->indexes[0];
}

double pq_GetMinValue(PQueue queue) {
  if(!queue->size)
    return -1;
  return queue->heap[0];
}

void pq_Delete(PQueue queue) {
  free(queue->heap);
  free(queue->indexes);
}

int main() {
    FILE *fd = fopen("algsort.in", "r+");
    FILE *fr = fopen("algsort.out", "w+");
    int32_t *array = malloc(sizeof(int32_t) * 500020);
    int32_t index = 0;
    PQueue priority = pq_New();
    int32_t n, a;
    fscanf(fd, "%d", &n);
    for(int32_t i = 0; i < n; i++) {
        fscanf(fd, "%d", &a);
        pq_Push(priority, (int32_t)a, i);
    }
    for(int32_t i = 0; i < n; i++) {
        fprintf(fr, "%d ", (int32_t)pq_GetMinValue(priority));
        array[index++] = (int32_t)pq_GetMinValue(priority);
        pq_DeleteHead(priority);
    }
    // for(int32_t i = 0; i < n - 1; i++) {
    //     if(priority->heap[i] > priority->heap[i + 1]) {
    //         printf("Wrong %f %f %f", i, priority->heap[i], priority->heap[i + 1]);
    //         exit(0);
    //     }
    // }
    pq_Delete(priority);
    fclose(fd);
    fclose(fr);
}