zoukankan      html  css  js  c++  java
  • 排序(插入,冒泡与归并)——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)

  • 相关阅读:
    移动开发 Native APP、Hybrid APP和Web APP介绍
    urllib与urllib2的学习总结(python2.7.X)
    fiddler及postman讲解
    接口测试基础
    UiAutomator2.0 和1.x 的区别
    adb shell am instrument 命令详解
    GT问题记录
    HDU 2492 Ping pong (树状数组)
    CF 567C Geometric Progression
    CF 545E Paths and Trees
  • 原文地址:https://www.cnblogs.com/liangchao/p/2677712.html
Copyright © 2011-2022 走看看