Cod sursa(job #2076609)

Utilizator DysKodeTurturica Razvan DysKode Data 26 noiembrie 2017 20:52:37
Problema Sortare prin comparare Scor 40
Compilator c Status done
Runda Arhiva educationala Marime 7.71 kb
#include <stdio.h>
#include <stdlib.h>

#define ListType int

typedef struct _CC_LIST_ENTRY{
    int Value;
    struct _CC_LIST_ENTRY *Pre, *Urm;
} CC_LIST_ENTRY;

int LstCreate( CC_LIST_ENTRY **List )
{
    /// primul nod din lista va tine minte numarul de elemente din lista
    *List = ( CC_LIST_ENTRY * )malloc( sizeof( CC_LIST_ENTRY ) );
    if( *List == 0 ) return -1;
    (*List) -> Value = 0;
    (*List) -> Pre = (*List) -> Urm = *List;
    return 0;
}

int LstDestroy( CC_LIST_ENTRY **List )
{
    free( *List );
    return 0;
}

///Intrebare daca se insereaza in List sau daca se insereaza la inceputul listei sau la sfarsitul ei
///Momentan insereaza la finalul listei
int LstInsertValue( CC_LIST_ENTRY *List, ListType Value )
{
    ///Complexitate O(1)
    ///Creez un nou nod si fac legaturile intre el si vecinii lui
    CC_LIST_ENTRY *aux, *newNode;
    aux = List -> Pre;
    newNode = ( CC_LIST_ENTRY * )malloc( sizeof( CC_LIST_ENTRY ) );
    if( newNode == 0 ) return -1;
    newNode -> Value = Value;
    newNode -> Pre = aux;
    newNode -> Urm = List;
    aux -> Urm = newNode;
    List -> Pre = newNode;
    ///Cresc numarul de noduri din lista
    List -> Value = List -> Value + 1;
    return 0;
}

///Intrebare daca e nevoie de List, lista este dublu inlantuita, se pot relationa vecinii lui Node si sterge Node
///Raspuns personal: pentru modificarea numarului de noduri
int LstRemoveNode( CC_LIST_ENTRY *List, CC_LIST_ENTRY *Node )
{
    ///Complexitate O(1)
    Node -> Pre -> Urm = Node -> Urm;
    Node -> Urm -> Pre = Node -> Pre;
    free( Node );
    List -> Value = List -> Value - 1;
    return 0;
}

int LstGetNodeValue( CC_LIST_ENTRY *Node, ListType *Value )
{
    ///Complexitate O(1)
    *Value = Node -> Value;
    return 0;
}

int LstGetNodeCount( CC_LIST_ENTRY *List )
{
    ///Complexitate O(1)
    return List -> Value;
}

int LstGetNthNode( CC_LIST_ENTRY *List, int Index, CC_LIST_ENTRY **Node )
{
    ///Complexitate O(n) worst case
    int n = List -> Value;
    CC_LIST_ENTRY *aux;
    ///Mergem pe drumul cel mai scurt 1->Index sau n->Index
    if( n - Index < Index )
    {
        aux = List -> Pre;
        for( int i = n ; i > Index ; i-- )
        {
            aux = aux -> Pre;
        }
    }
    else
    {
        aux = List -> Urm;
        for( int i = 1 ; i < Index ; i++ )
        {
            aux = aux -> Urm;
        }
    }
    *Node = aux;
    return 0;
}

int LstClear( CC_LIST_ENTRY *List )
{
    ///Complexitate O(n)
    int n = List -> Value;
    CC_LIST_ENTRY *del;
    for( int i = 1 ; i <= n ; i++ )
    {
        LstGetNthNode( List , 1 , &del );
        LstRemoveNode( List , del );
    }
    return 0;
}

int LstMergeSortedList( CC_LIST_ENTRY *Destination, CC_LIST_ENTRY *Source )
{
    ListType *aux = ( ListType * )malloc( sizeof( ListType ) * ( Destination -> Value + Source -> Value ) );
    ListType *aV = ( ListType * )malloc( sizeof( ListType ) * Destination -> Value );
    ListType *bV = ( ListType * )malloc( sizeof( ListType ) * Source -> Value );
    if( aux == 0 || aV == 0 || bV == 0 ) return -1;
    CC_LIST_ENTRY *a = Destination;
    int nr = 0;
    for( int i = 1 ; i <= Destination -> Value ; i++ )
    {
        a = a -> Urm;
        aV[ i - 1 ] = a -> Value;
    }
    a = Source;
    for( int i = 1 ; i <= Source -> Value ; i++ )
    {
        a = a -> Urm;
        bV[ i - 1 ] = a -> Value;
    }
    int A=0,B=0;
    while( A < Destination -> Value || B < Source -> Value )
    {
        if( A == Destination -> Value )
        {
            aux[ nr++ ] = bV[ B++ ];
        }
        else if( B == Source -> Value )
        {
            aux[ nr++ ] = aV[ A++ ];
        }
        else if( aV[ A ] > bV[ B ] )
        {
            aux[ nr++ ] = bV[ B++ ];
        }
        else
        {
            aux[ nr++ ] = aV[ A++ ];
        }
    }
    free( aV );
    free( bV );
    A = Source -> Value + Destination -> Value;
    LstClear( Destination );
    for( int i = 1 ; i <= A ; i++ )
    {
        LstInsertValue( Destination , aux[ i - 1 ] );
    }
    free( aux );
    return 0;
}

int MergeSortLst( ListType *vec , int Left, int Right )
{
    ///Complexitate O(1)
    if( Right - Left == 0 ) return 0;
    int Middle = Left + ( Right - Left ) / 2;
    ///Sortez cele doua jumatati ale vectorului
    if( MergeSortLst( vec , Left , Middle ) == -1 ) return -1;
    if( MergeSortLst( vec , Middle + 1 , Right ) == -1 ) return -1;

    int A = Left, B = Middle + 1, i = 0; /// pentru interclasare se vor folosi indicii A ( jumatatea stanga ) si B ( jumatatea dreapta )
    ListType *aux; /// si un vector auxiliar
    aux = ( ListType * )malloc( ( Right - Left + 1 ) * sizeof( ListType ) );
    if( aux == 0 ) return -1;
    while( A <= Middle || B <= Right )
    {
        ///fac interclasarea a celor doua jumatati
        if( A == Middle + 1 )
        {
            aux[ i++ ] = vec[ B++ ];
        }
        else if( B == Right + 1 )
        {
            aux[ i++ ] = vec[ A++ ];
        }
        else if( vec[ A ] <= vec[ B ] )
        {
            aux[ i++ ] = vec[ A++ ];
        }
        else
        {
            aux[ i++ ] = vec[ B++ ];
        }
    }
    ///copiez in vector auxiliarul si dealoc memoria auxiliarului
    for( int i = Left ; i <= Right ; i++ )
    {
        vec[ i ] = aux[ i - Left ];
    }
    free( aux );
    return 0;
}

int LstSortByValues( CC_LIST_ENTRY *List )
{
    ListType *vec;
    int n = List -> Value;
    vec = ( ListType * )malloc( sizeof( ListType ) * n );
    for( int i = 0 ; i < n ; i++ )
    {
        List = List -> Urm;
        vec[ i ] = List -> Value;
    }
    List = List -> Urm;
    int rasp = MergeSortLst( vec , 0 , n - 1 );
    LstClear( List );
    for( int i = 0 ; i < n ; i++ )
    {
        LstInsertValue( List , vec[ i ] );
    }
    free( vec );
    return rasp;
}

void DisplayList( CC_LIST_ENTRY *List )
{
    int n = List -> Value;
    printf( "\n******\n" );
    for( int i = 1 ; i <= n ; i++ )
    {
        List = List -> Urm;
        int x;
        LstGetNodeValue( List , &x );
        printf( "%d " , x );
    }
    printf( "\n******\n" );
}

int main()
{
    /*
    FILE *fin = fopen( "algsort.in" , "r" );
    FILE *fout = fopen( "algsort.out" , "w" );
    CC_LIST_ENTRY *List,*A;
    LstCreate( &List );
    int i,n,x;
    while( scanf( "%d" , &n ) )
    {
        if( n == 1 )
        {
            scanf( "%d" , &n );
            LstInsertValue( List , n );
        }
        else if( n == 2 )
        {
            printf( "%d\n" , LstGetNodeCount( List ) );
        }
        else if( n == 3 )
        {
            scanf( "%d"  , &n);
            LstGetNthNode( List , n , &A );
            LstGetNodeValue( A , &n );
            printf( "%d\n" , n );
        }
        else if( n == 4 )
        {
            scanf( "%d"  , &n);
            LstGetNthNode( List , n , &A );
            LstRemoveNode( List , A );
        }
        else if( n == 5 )
        {
            DisplayList( List );
        }
        else
        {
            LstSortByValues( List );
        }
    }*/
    FILE *fin = fopen( "algsort.in" , "r" );
FILE *fout = fopen( "algsort.out" , "w" );
    CC_LIST_ENTRY *List,*A;
    LstCreate( &List );
    int i,n,x;
    fscanf( fin , "%d" , &n );
    for( i = 1 ; i <= n ; i++ )
    {
        fscanf( fin , "%d" , &x );
        LstInsertValue( List , x );
    }
    LstSortByValues( List );
    for( i = 1 ; i <= n ; i++ )
    {
        LstGetNthNode( List , i , &A );
        LstGetNodeValue( A , &x );
        fprintf( fout , "%d " ,x );
    }
    fprintf( fout , "\n" );
}