插入排序-《算法導論》學習筆記一

算法導論第二章的第一小節是插入排序,也就是像打撲克牌整理撲克一樣,從左邊第二張開始,每張與前邊排好序的撲克牌比較,比較到能插入的位置就插入,算法比較簡單。

#include <stdio.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

void insert_sort0( int* arr, int idx )
{
    int i = idx - 2;
    int tmp = arr[idx];

    arr[idx] = arr[idx - 1];

    for ( ; i >= 0; i-- ) {
        if ( arr[i] > tmp )
            arr[i + 1] = arr[i];
        else {
            arr[i + 1] = tmp;
            break;
        }
    }
    if ( i < 0 )
        arr[0] = tmp;
}
int insert_sort( int* arr, int len)
{
    time_t t_old, t_new;
    t_old = time(NULL);
    if ( arr[0] > arr[1] ) {
        int tmp = arr[0];
        arr[0] = arr[1];
        arr[1] = tmp;
    }

    int i = 1;

    for ( ; i + 1< len; i++ ) {
        if ( arr[i + 1] < arr[i] ) {
            insert_sort0( arr, i + 1 );
        }
    }
    t_new = time(NULL);

    return (int)(t_new - t_old);
}
void sortLoop0( int *arr, int len )
{
    insert_sort( arr, len );
}
//排序前後做時間對比,精度sec
void sortLoop( int *arr, int len )
{
    time_t tt0 = time( NULL );
    printf("\tbefore sort:%s", ctime(&tt0));
    sortLoop0( arr, len );
    time_t tt1 = time( NULL );
    printf("\tafter sort:%s", ctime(&tt1));
    printf("\tsort the array cost %d(sec),%d(min)\n", 
        (int)(tt1 - tt0), (int)((tt1 - tt0) / 60));
}
//初始化隨機數組
void initArr( int *arr, int lowV, 
    int upV, int len )
{
    srand( (int)time(NULL) );
    int i = 0;
    int size = upV - lowV;

    for ( ; i < len; i++ )
    { 
        arr[i] = rand() % size + lowV;  
    }
}
//打印數組
void printArr( int *arr, int len )
{
    int i = 0;
    for ( ; i < len; i++ )
        printf("%d ", arr[i]);
    printf("\n");
}
//這裏寫了個簡單得數組檢查,檢查是否
//是正確的遞增序列(怕自己的代碼沒檢查
//邊界條件偶爾有錯誤的排序數組)
int check_arr_increase( int *arr, int len )
{
    int i = 0;

    for ( ; i < len - 1; i++ )
    {
        if ( arr[i] <= arr[i + 1] )
            continue;
        else 
        {
            printf("array isn't increase!!!\n");
            return -1;
        }

    }
    printf("array is increase!!!!\n");
    return 0;
}
int main( int argc, char **argv )
{
    if ( argc != 4 )
    {
        printf("usage: ./execfile lowV upV len\n");
        return 0;
    }

    int lowV = atoi( argv[1] );
    int upV = atoi( argv[2] );
    unsigned int len = atoi( argv[3] );

    int *arr = NULL;
    arr = ( int *) malloc( len * sizeof(int) );

    initArr( arr, lowV, upV, len );
    //printArr( arr, len );
    sortLoop( arr, len );
    check_arr_increase( arr, len );
    //printArr( arr, len );

    free( arr );
    arr = NULL;

    return 0;
}

我的ubuntu虛擬機環境是雙核3代i5,2G內存,排序10-100000的隨機10萬的數組如下情況:
這裏寫圖片描述
如果是100萬的數組,耗時10幾分鐘;如果是1000萬的數組,掛着跑了一晚上都沒排好序。

對插入排序的一點思考:在寫排序的時候想到當前數可以從排好序數組後往前比較,也可以從前往後比較,前一種比較一個不符合即可將比較的數組值後移一位,給待插入值讓位,這樣就在比較重順便後移,如果是後一種比較插入方法,則是遍歷排好序數組,直到找到符合的索引位置,將位置後邊的數組後移,這樣相當於每次都要遍歷一遍排好序數組,因此不用此方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章