C语言回顾--4大经典排序(快速、选择、冒泡、插入)函数体实现

 


前言:

常见的4种算法也是笔试、面试之中最常问的问题,甚至有些笔试题其实就是这4算法的变种题目:重要的是看清题目本质;


1.冒泡排序:平均复杂度:O(n^2) n~n^2 

void maopao( int *list,int n)    //list 为传入数组,n为数组中的个数
{
    int     i,j,temp;

    for(i = 0; ilist[j+1])
            {
                temp        = list[j];      //交换位置
                list[j]     = list[j+1];
                list[j+1]   = temp;
            }
        }

    printf("maopao finish!\n");

}

2.快速排序:平均复杂度:O(nlog n) nlog n~n^2 空间:log n ,以下是使用函数的递归法实现:

int Partition(int *arr,int low,int high)
{
    int i = low;                                        
    int j = high;

    int temp;    //用于i和j交换的容器;

    int pivotKey = arr[i];    //用于存放基准值的容器;

    while(i < j)
    {
        while( i < j && arr[j] >= pivotKey)  //j寻找小于基准值的数
        {
            j--;
        }

        while( i < j && arr[i] <= pivotKey) //i寻找大于基准值的数
        {
            i++;
        }

        if(i < j)                //将i 和 j所找到的数进行交换
        {
            temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }

    }    // 当i和j相遇时,就是基准的位置;
    arr[low] = arr[i];
    arr[i] = pivotKey;

    return i;    //返回基准的位置
}

void QuickSort(int arr[], int low,int high)
{
    int     pivotpos;
    int     i;

    if(low < high)
    {
        pivotpos = Partition(arr,low,high);    //获得划分区域的基准值

        QuickSort(arr,low,pivotpos-1);    //将小于基准的左侧区域进行排序

        QuickSort(arr,pivotpos+1,high);   ////将大于基准的左侧区域进行排序
    }
}

注:

在本程序中,必须先执行寻小的值,也就是先进行while(.....){j--},否则会导致排序失败,原因是i和j相遇时,如果i指向的值大于基准值,由于先遍历的是i,所以会导致错误的交换.举个例子:13 38 27 -----> 38 13 27

3.选择排序:平均时间复杂度O(n^2) 好坏都是O(n^2) 空间复杂度为O(1)

void selectionSort(int arr[],int length)
{
    int             i,j;
    int             minIndex;
    int             temp;

    if( length <= 0 )
    {
        printf("Error:arr size is NULL\n");
        return ;
    }

    for( i = 0; i < length; i++ )    //遍历整个数组,并且用minIndex容器存放
    {
        minIndex = i;
        for( j = i; j < length ;j++ ) //在i的基础上也遍历整个数组,找比min容器更小的值,并更新容器
        {
            if( arr[j] < arr[minIndex] )
            {
                minIndex = j;
            }
        }
        
        temp = arr[minIndex];    //结束一次j循环后进行交换;
        arr[minIndex] = arr[i];
        arr[i] = temp;
    
    }

}

 

4.插入排序:平均时间复杂度:O(n^2) n~n^2 空间复杂度(O(1))

void insertionSort(int arr[],int length)
{
    int         i;
    int         current;
    int         preIndex;

    if(length <= 0)
    {
        printf("Error input length size :%d\n",length);
        return ;
    }
    
    for( i = 0; i < length -1; i++)    //length -1 的目的,由于current是在i的前提加1,因此防止越界
    {
        current = arr[i+1];
        preIndex = i;

        while(preIndex >= 0 && current < arr[preIndex])    //跳出条件,preIndex 小于0和找到大于arr[preIndex]的值
        { 
            arr[preIndex + 1] = arr[preIndex]; //交换前半部;

            preIndex--;//向后寻找
        }

        arr[preIndex + 1] = current; //2各功能,1个是自己给自己赋值(右相邻的值比自己大),一个是交换(右值你自己小,进行交换,完成交换后半部)
    }
    return;

}

以上是4种排序函数体的实现以下是main函数体:

int main (int argc, char **argv)
{
    int a[8] = {88,37,97,28,27,45,56,92};
    int i=0; 

#if 1
    QuickSort(a,0,7);
#endif

#if 0 
    maopao(a,8);
#endif

#if 0 
    selectionSort(a,8);
#endif

    
#if 0 
    insertionSort(a,8);
#endif
   
    for(i = 0;i<8;i++)
    {
        printf("%d\n",a[i]); 
    }
    return 0;
} /* ----- End of main() ----- */

 

 

 

你可能感兴趣的:(学习以及回顾数据结构)