排序

// 全体のプログラム例(発展問題含む) 
  
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h>
#define N 200000
void bubble_sort_array(int a[], int n);//バブルソート 
void selection_sort_array(int a[], int n);//選択ソート 
void insertion_sort_array(int a[], int n);//挿入ソート
void merge_sort(int array[], int first, int last);
void quick_sort(int ary[], int left, int right);

unsigned long long int k;
int array[N],buff[N];
void main() 
{ 
    int i; 
    int n=N,num=0,count=0,seed; /*table, arrayに登録されているデータの個数*/
    int output[N]; 
      clock_t start, end;
    scanf("%d",&seed);
    srand(seed);
    //配列生成
    for(i=0;i<n;i++) 
    { 
        array[i] = rand()%114514; //ランダムに生成
        //hairetus[i] = n - i - 1;で逆順生成
    } 
    k = 0;
    start = clock();
    selection_sort_array(array, n); //選択ソート 
    end = clock();
    printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
    printf("\n step is %llu\n",k);
    k = 0;


    srand(seed);
    //配列生成
    for(i=0;i<n;i++) 
    { 
        array[i] = rand()%114514; //ランダムに生成
        //hairetus[i] = n - i - 1;で逆順生成
    } 
    start = clock();
    insertion_sort_array(array, n); //挿入ソート 
    end = clock();
    printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
    printf("\n step is %llu\n",k);


    srand(seed);

    //配列生成
    for(i=0;i<n;i++) 
    { 
        array[i] = rand()%114514; //ランダムに生成
        //hairetus[i] = n - i - 1;で逆順生成
    } 
    start = clock();
    quick_sort(array,0, n-1); //QUICKソート 
    end = clock();
    printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
    printf("\n step is %llu\n",k);


    srand(seed);

    //配列生成
    for(i=0;i<n;i++) 
    { 
        array[i] = rand()%114514; //ランダムに生成
        //hairetus[i] = n - i - 1;で逆順生成
    } 
    k = 0;
    start = clock();
    for(i=0;i<N;i++)
    {
        insert(array, N - i , count);
        count++;
    }
    num = N;
    for(i = 1; i <= N; i++)
    {
        output[i] = delete_root(array, &num);
    }
    end = clock();
    printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
    printf("\n step is %llu\n",k);


    k=0;
    srand(seed);
    //配列生成
    for(i=0;i<n;i++) 
    { 
        array[i] = rand()%114514; //ランダムに生成
        //hairetus[i] = n - i - 1;で逆順生成
    } 


    start = clock();
    merge_sort(array,0,N-1);
    end = clock();
    printf("%.6f sec\n",(double)(end-start)/CLOCKS_PER_SEC);
    printf("\n step is %llu\n",k);

} 
  
  
//バブルソート
void bubble_sort_array(int a[], int n) 
{ 
    int i, j, t; 
    for(i = 0; i < n; i++) 
    { 
        for(j = n - 1; j > i; j--) 
        { 
            if(a[j] < a[j-1]) 
            { 
                //交換
                t = a[j]; 
                a[j] = a[j-1]; 
                a[j-1] = t; 
            } 
        } 
    } 
} 
  
  
//選択ソート
void selection_sort_array(int a[], int n) 
{ 
    int i, j, t, lowest, lowkey;
    for(i = 0; i < n - 1; i++) 
    { 
        k++;
        //lowest:最小値の値 lowkey:最小値の値を格納する要素の添え字
        //とりあえず最小値の値をa[i]としておく
        lowest = a[i];
        k++;
        lowkey = i;
        k++;
        for(j = i + 1; j < n ; j++) 
        { 
            k++;
            //lowestより低い値を格納する要素が見つかった場合、lowestを更新する
            if(lowest > a[j]){ 
                k++;
                lowest = a[j]; 
                k++;
                lowkey = j; 
                k++;
            } 
        } 
        //交換
        t = a[i];
        k++;
        a[i] = a[lowkey];
        k++;
        a[lowkey] = t;
        k++;
    } 
} 
  
//挿入ソート
void insertion_sort_array(int a[], int n) 
{ 
    int i, j, t;
    for(i = 1; i < n; i++) //
    { 
        k++;
        j = i;  //未ソート部分の先頭の添え字
        k++;
        while(a[j-1] > a[j] && j>0)//未ソート部分の先頭を適切な位置へ挿入
        {
                k++;
                // 交換作業
                t = a[j-1];
                k++; 
                a[j-1] = a[j];
                k++;
                a[j] = t;
                k++;
                j--;
                k++;
        } 
    } 
}

void upHeap(int array[], int n)
{
    int tmp, size;
    size = n;
    k++;
    while(array[n] < array[n/2] && n != 1)
    {
        tmp = array[n];
        k++;
        array[n] = array[n/2];
        k++;
        array[n/2] = tmp;
        k++;
        
        n = n / 2;
        k++;
    }
    
}

void downHeap(int array[], int n, int size)
{
    int tmp, bigger;

    if(2*n > size)
    {
        k++;
        return;
    }
    else if(2*n + 1 > size || array[2*n] < array[2*n+1])
    {
        k++;
        k++;
        bigger = 2*n;
    }
    else
    {
        k++;
        k++;
        bigger = 2*n+1;
    }
    
    if(array[n] > array[bigger])
    {
        k++;
        tmp = array[bigger];
        k++;
        array[bigger] = array[n];
        k++;
        array[n] = tmp;
        k++;
        downHeap(array, bigger, size);
        k++;
    }
    else
    {
        k++;
        return;
    }
}

int insert(int array[], int x, int count)
{
    array[count + 1] = x;
    k++;
    upHeap(array, count + 1);
    k++;
    return 1;
}

int delete_root(int array[], int *num)
{
    int tmp,ret;
    
    tmp = array[1];
    k++;
    ret = array[1];
    k++;
    array[1] = array[*num];
    k++;
    array[*num] = -1;
    k++;
    *num = *num - 1;
    k++;
    downHeap(array, 1, *num);
    k++;

    return ret;
}

void merge(int a[],int as,int b[],int bs,int c[]){ //併合するだけの関数
    int pa=0;//配列aの現在地
    int pb=0;//配列bの現在地
    int pc=0;//配列cの現在地

    while(pa<as && pb<bs){
        if(a[pa]<b[pb]){
            c[pc]=a[pa];
            pc++;
            pa++;
        }else{
            c[pc]=b[pb];
            pb++;
            pc++;
        }
    }
    while(pa<as){
        c[pc]=a[pa];
        pc++;
        pa++;
    }
    while(pb<bs){
        c[pc]=b[pb];
        pc++;
        pb++;
    }
}
void merge_sort(int array[],int first,int last){
    int center=(first+last)/2;
    int i,j;

    if(first<last){
        merge_sort(array,first,center);
        merge_sort(array,center+1,last);

        for(i=first;i<=last;i++){
            buff[i]=array[i];
        }
        
        merge(&buff[first],center-first+1,&buff[center+1],last-center,&array[first]);

    }
}

void quick_sort(int ary[], int left, int right)
{
    int arL, arR, pivot, tmp, l_stack[1000], r_stack[1000], ptr=0;
    //値の設定.arLとarRは大小探索に利用する.
    arL = left;
    arR = right;
    l_stack[ptr] = left;
    r_stack[ptr] = right;
    ptr++;
    //pivot決定
    while (ptr-- >0) { 
        arL = left = l_stack[ptr];
        arR = right = r_stack[ptr];
        pivot = arL;
        //探索部分と交換操作
        while(arL <= arR)
        {
            for(arL = arL; ary[arL] < ary[pivot]; arL++)
            {}
            for(arR = arR; ary[arR] > ary[pivot]; arR--)
            {}

            if(arL <= arR)
            {
                tmp = ary[arL];
                ary[arL] = ary[arR];
                ary[arR] = tmp;
                arL++;
                arR--;
            }
        }
        if (arR - left < right - arL) {
            tmp = left;
            left = arL;
            arL = tmp;
            tmp = right;
            right = arR;
            arR = tmp;
        }
        if(left  < arR){
            l_stack[ptr] = left;
            r_stack[ptr] = arR;
            ptr++;
        }
        if(right > arR){
            l_stack[ptr] = arL;
            r_stack[ptr] = right;
            ptr++;
        }
    }
}

 

posted @ 2014-11-18 15:03  shankun  阅读(116)  评论(0)    收藏  举报