DSAA 第一章 引論

練習(p12)
1.1數組

/*
*   date:       2016-01-14 
*   question:   編寫一個程序解決選擇問題,令 k = N/2。 
*/
#include <stdlib.h>         // use rand () and srand () 動態生成數組
#include <stdio.h>
#include <stdbool.h>        // use bool 
#include <time.h>           // use clock () 計時    use time () 做爲 seed
#define MAXLENGTH 500000

void bubble_sort (int a[], int length);
void insert_sort (int a[], int length);
void fun1 (int a[], int length);        // 方法1 
void fun2 (int a[], int length);        // 方法2 
void print_array (int a[], int length); // 打印輸出數組 

int main (void)
{
    int N;
    int i;      // index 
    int a[MAXLENGTH];
    clock_t start, finish;          // 分別記錄開始和結束時的 clock() 值
     
// 用隨機函數產生數組 
    printf ("How many numbers you want to analysis?(q to quit)\n");
    while (scanf ("%d", &N) == 1)       // 循環進行輸入分析過程。 
    {
        srand (time (0));           // use current time as seed for random generator
        for (i = 0; i < N; i++)
        {
            a[i] = rand() % N;
        }
    //  printf ("the array generated is:\n");
    //  print_array (a, N);
        
        start = clock();
        fun1 (a, N);            // 第一種方法,用冒泡法排序。 
    //  fun2 (a, N);            // 第二種方法,利用到了插入排序 
        finish = clock();
        printf ("CPU time used %.2f ms\n", 1000 * (double) (finish - start) / CLOCKS_PER_SEC);      // 以毫秒計         
        printf ("How many numbers you want to analysis?(q to quit)\n"); 
    }
    
    return 0;
} 

// 方法一 利用冒泡排序 
void fun1 (int a[], int length)
{
    bubble_sort (a, length);
//  printf ("Now the array is:\n");
//  print_array (a, length);
    printf ("The %dth big number is %d\n", length/2, a[length/2 - 1]);
}

// bubble sort max to min
void bubble_sort (int a[], int length)
{
    int i, j, temp;
    bool swap;
    for (i = 0; i < length - 1; i++)        // length - 1 times
    {
        swap = false;
        for (j = 0; j < length -1 -i; j++)
        {
            if (a[j] < a[j+1])
            {
                swap = true;
                temp = a[j];
                a[j] = a[j+1];
                a[j+1] = temp;
            }
        }
        if (!swap)
            break;
    }
    return;
}

// 第二種方法 利用插入排序 
void fun2 (int a[], int length)
{
    int b[length / 2];          // 長度爲  length / 2
    int i, j;
    // 構造 b 數組 爲 a 的前 length / 2 個 元素所構成, 並遞減排序 
    for (i = 0; i < length / 2; i++)
    {
        b[i] = a[i];
    }
    insert_sort (b, length / 2);
//  printf ("array b:\n");
//  print_array (b, length / 2);    
    // 開始向 b 中插入剩下的 a 中元素   思想與插入排序相似,只是注意對於 b 中 最後一個元素的處理。要用倒數第二個去覆蓋,而不用後移。 
    for (i = length / 2; i < length; i++) 
    {
        if (a[i] <= b[length / 2 - 1])      // 比 b 的最後一個元素小,不插入 
            continue;
        // 比最後一個元素大,插入。 
        for (j = length / 2 - 2; j >= 0 ; j--)  // a[i] 直接與 b 的倒數第二個元素比較 
        {
            if (a[i] > b[j])
            {
                b[j+1] = b[j];   
            }
            else
                break; 
        }
        if (j >= 0)
            b[j+1] = a[i];
        else
            b[0] = a[i];    
    }
//  printf ("Now the array is:\n");
//  print_array (b, length/2);
    printf ("The %dth big number is %d\n", length/2, a[length / 2 - 1]);
}

// 插入排序 下標從0開始,與以前所學有略微差異。
void insert_sort (int a[], int length) 
{
    int i, j, temp;
    
    for (i = 1; i < length / 2; i++)
    {   
        temp = a[i];
        for (j = i-1; j >= 0; j--)
        {
            if (temp > a[j])        // temp 較大,把小的後移 
                a[j+1] = a[j];      // 將小的元素後移
            else                    // temp 較小, 則需考慮將temp插入 
                break;
        }
        if (j >= 0)
            a[j+1] = temp;
        else                // j < 0 即 j = -1 說明 temp > b[0] 
            a[0] = temp;
    }
}


// 打印整型數組 
void print_array (int a[], int length) 
{
    int i;
    for (i = 0; i < length; i++)
        printf ("%d\t", a[i]);
    printf ("\n");
}




/*
when I use fun1 to do this, the time(ms) table :
 
N:  100     1000    2000    4000    10000   15000   20000   30000   40000   50000
T:  0.18    9.13    35.30   103.27  370.25  800.65  1373.49 3013.20 5324.30 8325.52
N:  60000   70000   80000   90000   100000
T:  12301.9 16343.7 22047.7 29176.4 33550.90
when I use fun1 to do this, the time table :

N:  100     1000    2000    4000    10000   15000   20000   30000   40000   50000
T:  0.06    0.35    0.94    3.25    18.54   39.57   61.20   110.23  161.23  215.09
N:  60000   70000   80000   90000   100000
T:  271.17  358.10  411.38  490.30  600.65

可見,方法二比方法一好不少,固然,做者說還有更好的方法,拭目以待
*/
相關文章
相關標籤/搜索