Cod sursa(job #1694137)

Utilizator sdwolfSDWOLF sdwolf Data 24 aprilie 2016 19:40:43
Problema Sortare prin comparare Scor 20
Compilator c Status done
Runda Arhiva educationala Marime 5.06 kb
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

void read_input(int **list, int *size);
void flash_sort(int *list, int size);
void hulk_sort(int *list, int low, int high);
void exchange(int *first, int *second);
int select_pivot(int *list, int low, int high);
void write_output(int *list, int size);

int main() {
  int size;
  int *list;

  srand(time(NULL));

  read_input(&list, &size);
  flash_sort(list, size);
  write_output(list, size);

  return 0;
}

void read_input(int **list, int *size) {
  FILE *input = fopen("algsort.in", "r");

  fscanf(input, "%d\n", size);

  *list = (int*) malloc(sizeof(int) * (*size));

  for (int index = 0; index < *size; index +=1) {
    fscanf(input, "%d", *list + index);
  }

  fclose(input);
}

void flash_sort(int *list, int size) {
  int pivot, pivot_position, sort_threshold, carry;
  int left, left_low, left_high, right, right_low, right_high;

  int equal_left, equal_right;

  int *partition_low, *partition_high;
  int partition_size, partition_start, partition_end;

  partition_size  = 200000; //(int)  ceil(log2((float) size) * 3);
  partition_low   = (int*) malloc(sizeof(int) * (partition_size));
  partition_high  = (int*) malloc(sizeof(int) * (partition_size));

  sort_threshold = 10;

  left_low   = 0;
  right_high = size -1;

  partition_start = -1;
  partition_end   = 0;

  partition_low[partition_end]  = left_low;
  partition_high[partition_end] = right_high;

  // printf("List: ");
  for (int index = 0; index < size; index +=1) {
    // printf("%d ", list[index]);
  }
  // printf("\n");

  while(partition_start < partition_end) {
    partition_start += 1;

    // printf("Start: %d End: %d\n", partition_start, partition_end);

    left_low   = partition_low[partition_start];
    right_high = partition_high[partition_start];

    equal_left  = left_low;
    equal_right = right_high;

    if (right_high - left_low <= sort_threshold) {
      hulk_sort(list, left_low, right_high);

      // printf("Insertion: %d %d\n", left_low, right_high);

      // printf("List: ");
      for (int index = 0; index < size; index +=1) {
        // printf("%d ", list[index]);
      }
      // printf("\n");

      continue;
    }

    pivot_position = select_pivot(list, left_low, right_high);

    // printf("Position: %d Pivot: %d\n", pivot_position, list[pivot_position]);

    left  = left_low;
    right = right_high;

    pivot = list[pivot_position];

    // printf("Range: %d - %d\n", left, right);

    while (1) {
      while(list[left]  < pivot) left  += 1;
      while(list[right] > pivot) right -= 1;

      // printf("Left: %d Right: %d Position: %d\n", left, right, pivot_position);

      // printf("List Before: ");
      for (int index = 0; index < size; index +=1) {
        // printf("%d ", list[index]);
      }
      // printf("\n");

      if (left >= right) break;

      exchange(&list[left], &list[right]);

      if (list[left] == pivot) {
        exchange(&list[left], &list[equal_left]);
        equal_left += 1;
      }

      if (list[right] == pivot) {
        exchange(&list[right], &list[equal_right]);
        equal_right -= 1;
      }

      // printf("Pivot Position: %d\n", pivot_position);
      // printf("EQL: %d EQR: %d\n", equal_left, equal_right);

      // printf("List After:  ");
      for (int index = 0; index < size; index +=1) {
        // printf("%d ", list[index]);
      }
      // printf("\n");
    }

    for (int index = left_low; index < equal_left; index += 1) {
      exchange(&list[index], &list[equal_left]);
      equal_left -= 1;
    }

    left_high = equal_left;

    if (left_high > left_low) {
      partition_end                 += 1;
      partition_high[partition_end] = left_high;
      partition_low[partition_end]  = left_low;

      // printf("Added: %d %d\n", partition_high[partition_end], partition_low[partition_end]);
    }

    for (int index = right_high; index > equal_right; index -= 1) {
      exchange(&list[index], &list[equal_right]);
      equal_right += 1;
    }

    right_low = equal_right;

    if (right_low < right_high) {
      partition_end                 += 1;
      partition_high[partition_end] = right_high;
      partition_low[partition_end]  = right_low;

      // printf("Added: %d %d\n", partition_high[partition_end], partition_low[partition_end]);
    }
  }
}

void hulk_sort(int *list, int low, int high) {
  int carry;

  for (int first = low; first < high; first += 1) {
    for (int second = first + 1; second <= high; second += 1) {
      if (list[first] > list[second]) {
        exchange(&list[first], &list[second]);
      }
    }
  }
}

void exchange(int *left, int *right) {
  int carry  = *left;
  *left      = *right;
  *right     = carry;
}

int select_pivot(int *list, int low, int high) {
  return rand() % (high - low) + low;
}

void write_output(int *list, int size) {
  FILE *output = fopen("algsort.out", "w");

  int last = size - 1;

  for (int index = 0; index < size; index +=1) {
    if (index < last) {
      fprintf(output, "%d ", list[index]);
    } else {
      fprintf(output, "%d", list[index]);
    }
  }
  fprintf(output, "\n");

  fclose(output);
}