排序(插入,冒泡与归并)——C语言

    写几个基础的算法,虽然很基础,但要是让我毫无准备立马写下还真写不顺畅,加上面试时候的紧张气氛,立马嗝屁。

1.插入排序

基本思想是将一个为排序元素插入到已排序的一系列元素中,关键点:1.找到元素应该处在的位置 2.插入元素

sorted1 sorted2 sorted3 ........ undeter

用链表实现会好一些,因为使用数组需要先移动一堆元素再插入,而链表直接插入即可,不过在C语言里使用链表得自己定义其实现和操作,比较麻烦(其实是我不大会),为了保护自己脆弱的自信心,这里就先简单用数组实现看看(实现递增排序)。

void insertion_sort( int a[], int length )        /*length为数组长度*/

{

    int i, j, key;

    for( i = 1; i < length; i++ )        /*将第一个元素a[0]视为已排序,因此从a[1]开始插入*/

    {

        key = a[i];        /*a[i]为待插入的元素*/

        j = i - 1;

        while( j >= 0 && a[j] > key )        /*向左找到第一个小于a[i]元素的位置*/

        {

            a[ j + 1 ] = a[j];        /*将大于a[i]的元素都向右移一位*/

            j--;

        }

        a[ j + 1 ] = key;        /*将a[i]的值插入到正确位置,位置j为第一个小于a[i]的元素*/

    }  

}

时间复杂度:O(n^2)

2.冒泡排序

基本思路是:每次比较相邻的两个数,小的在左,大的在右,最终每轮比较都得到一个最大的数。

假设数组长度为len,那么最大的数就要放在a[len - 1], 第二大的数放在a[len - 2],以此类推。因此外层循环就是要从len-1~0,每次循环都得到一个最大的数。

void bubble_sort( int a[], int length )

{

    int i, j;

    for( i = length - 1; i > 0; i-- )

    {

        for( j = 0; j < i; j++ )        /*内循环比较相邻的两个数*/

        {

            if( a[j + 1] < a[j] )

                swap( a, j, j + 1 );        /*自己定义一个元素交换函数*/

        }

    }

}

时间复杂度:O(n^2)

3.归并排序

基本思想:每个递归过程都对已排序的两个数组进行合并,在合并的过程中完成排序操作。

具体实现:

void merge( int a[], int start, int mid, int end )        /*先定义合并函数,作用是将数组中已排序的左右两部分按顺序合并*/

{

    int n1 = mid - start + 1;
    int n2 = end - mid;
    int left[100], right[100];        /*这里如果用left[n1], right[n2]定义的话会报错,所以就用了固定长度的数组*/
    int i, j, k;
    for( i = 0; i < n1; i++ )
        left[i] = a[start + i];
    for( j = 0; j < n2; j++ )
        right[j] = a[mid + 1 + j];
    i = 0;
    j = 0; 
    for( k = start; i < n1 && j < n2; ++k )
    {
        if( left[i] < right[j] )

        {

            a[k] = left[i]; 
            ++i;
        }
        else
        {
            a[k] = right[j];
            ++j;
        }
    }
    if( i < n1 )
        for( ; i < n1; i++ )
        {
            a[k] = left[i];
            ++k;
        }
    if( j < n2 )
        for( ; j < n2; ++j )
        {
            a[k] = right[j];
            ++k;
        }

}

void merge_sort( int a[], int start, int end )        /*start与end分别为起始和终止位置*/

{

    int mid;

    if( start < end )

    {

        mid = ( start + end ) / 2;

        merge_sort( a, start, mid );        /*对左半部分进行排序*/

        merge_sort( a, mid + 1, end );         /*对右半部分进行排序*/

        merge( a, start, mid, end );        /*合并两个排序的部分*/

    }

}

时间复杂度为O(nlogn)

 

 

 

 

posted @ 2012-09-09 20:08  糙哥  阅读(330)  评论(0编辑  收藏  举报