Cod sursa(job #1018287)

Utilizator sziliMandici Szilard szili Data 29 octombrie 2013 10:33:20
Problema Sortare prin comparare Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.84 kb
#include <iostream>
#include <stdio.h>
#include <stdlib.h>;

using namespace std;

int a[500001];
int n;

int selections[100001];

int smallerNumbers[500001];
int biggerNumbers[500001];



int cmp(const void *first, const void *second){

    if (*(int*)first < *(int*) second){
        return -1;
    } else if (*(int*)first == *(int*) second){
        return 0;
    } else {
        return 1;
    }
}

int getMedianOf(int *a, int left, int right){
    int threshold = 3;

    int bb[5];

    for (int i=left; i<=right; i++){
        bb[i-left] = a[i];
    }

    qsort(bb, 5, sizeof(int), &cmp);

    return bb[2];
}

int *partitionX(int *a, int aSize, int M, int *calculatedSize){

    *calculatedSize = 0;

    for (int i=0; i<aSize; i++){
        if (a[i] < M){
            biggerNumbers[(*calculatedSize)++] = a[i];
        }
    }

    return biggerNumbers;
}


int *partitionZ(int *a, int aSize, int M, int *calculatedSize){

    *calculatedSize = 0;

    for (int i=0; i<aSize; i++){
        if (a[i] > M){
            smallerNumbers[(*calculatedSize)++] = a[i];
        }
    }

    return smallerNumbers;
}

int *obtainMediansOfGroupsOf5(int *a, int n){

    for (int i=0; i< (n/5); i++){
        int x = getMedianOf(a, i*5, i*5+4);
        selections[i] = x;
    }

    return selections;
}

int selection(int *a, int k, int n){

    if (n <= 10){
        qsort(a, n, sizeof(int), &cmp);

        return a[k-1];
    }

    int *medians = obtainMediansOfGroupsOf5(a, n);

    int M = selection(medians, n/10, n/5);

    int sizeX, sizeZ;
    int *x = partitionX(a, n, M, &sizeX);
    int *z = partitionZ(a, n, M, &sizeZ);

    int sizeY = n - sizeX - sizeZ;

    if (k <= sizeX){
        return selection(x, k, sizeX);
    }
    else if (k <= sizeX + sizeY){
        return M;
    } else {
        return selection(z, k- sizeX - sizeY, sizeZ);
    }
}

void qsort(int left, int right){

    if (left < right){
        int pivot =  a[(left+right)/2];//selection(a+left, (right - left + 1)/2, (right-left)+1);
        int i= left;
        int j=right;
        int sw;

        while (i<=j){

            while (a[i] < pivot){
                i++;
            }

            while (a[j] > pivot){
                j--;
            }

            if (i <= j){
                sw = a[i];
                a[i] = a[j];
                a[j] = sw;
                i++;
                j--;
            }
        }

        qsort(left, j);
        qsort(i, right);
    }

}

int main()
{
    freopen("algsort.in", "r", stdin);
    freopen("algsort.out", "w", stdout);

    scanf("%d", &n);

    for (int i=0; i<n; i++){
        scanf("%d", &a[i]);
    }

    qsort(0, n-1);

    for (int i=0; i<n; i++){
        printf("%d ", a[i]);
    }

    return 0;
}