zoukankan      html  css  js  c++  java
  • C语言排序

    一、冒泡排序

    基本思想:(将相邻两个数比较,小的调到前头)  
    1)有n个数(存放在数组a(n)中),第一趟将每相邻两个数比较,小的调到前头,经n-1次两两相邻比较后,最大的数已“沉底”,放在最后一个位置,小数上升“浮起”;  
    2)第二趟对余下的n-1个数(最大的数已“沉底”)按上法比较,经n-2次两两相邻比较后得次大的数;  
    3)依次类推,n个数共进行n-1趟比较,在第j趟中要进行n-j次两两比较

    #include <stdio.h>
    #include <windows.h>
    int main() 
    {
        int a[10] = { 123, 34, 76, 31, 678, 94, 456, 29, 4, 23 };
        for (int j = 0; j < 10; j++)
        {
            for (int i = 0; i < 9; i++)
            {
                if (a[i] > a[i + 1])
                {
                    int b = 0;
                    b = a[i + 1];
                    a[i + 1] = a[i];
                    a[i] = b;
                    for (int k = 0; k < 10; k++){ printf("%d	", a[k]); }printf("
    ");
                    Sleep(500);
                }
            }
        }
    }

    二、选择排序

    基本思想:  
    1)对有n个数的序列(存放在数组a(n)中),从中选出最小的数,与第1个数交换位置;  
    2)除第1 个数外,其余n-1个数中选最小的数,与第2个数交换位置;  
    3)依次类推,选择了n-1次后,这个数列已按升序排列。 

    #include <stdio.h> 
    #include <windows.h>
    int main()
    {
        int a[10] = { 123, 34, 76, 31, 678, 94, 456, 29, 4, 23 };
        for (int i = 0; i < 10; i++)
        {
            int min = i;            //这个十分重要,每次循环之前初始化min的值 并且不再重复用前面的下标
            for (int j = i; j < 10; j++) //这个循环找出最小的那个值的下标
            {
                if (a[j] < a[min])
                {
                    min = j;
                }
            }
            if (a[min] != a[i])    //把刚才找到的那个min下标和前面他排名的位置互换
            {
                int b = a[min];
                a[min] = a[i];
                a[i] = b;
            }
            for (int k = 0; k < 10; k++){ printf("%d	", a[k]); }printf("
    ");
        }
    }

    三、直接插入排序

    基本思想:  

    1)第一个元素自己作为一个有序数组;

    2)从第二个元素开始,将它与其左侧第一个元素比较,若左侧第一个元素比它大,则继续与左侧第二个元素比较,直到遇到不大于(小于或等于)该元素的元素,将该元素插入到所找到的元素的右边,此时该元素及其左边的元素是已排序的;

    3)选取第 3、4、...、n 个元素,重复步骤 2;

    4)得到有序的数

    #include <stdio.h> 
    #include <windows.h>
    int main()
    {
        int a[10] = { 123, 34, 76, 31, 678, 94, 456, 29, 4, 23 };
        for (int i = 1; i < 10; i++)//从第二个数开始
        {
            int b = a[i];
            int p = i - 1;
            while (p >= 0 && b < a[p])//把所有比a[i]大的数全换到后面去
            {
                a[p + 1] = a[p];
                p--;
            }
            a[p + 1] = b;
            for (int k = 0; k < 10; k++){ printf("%d	", a[k]); }printf("
    ");
        }
    }

    四、希尔排序

    首先、先把一个数组按照一定间隔,分成两两一组的结合,同时对比这两个数据,排序

    然后、再按照另一个间隔重复刚才的步骤

    接下来、直到间隔为1,也就是相邻的两个数据为一组,做一次直插排序

    间隔一般为数组长度的1/2,第二次为1/4,第三次1/8以此类推,直到间隔为1

    下列代码中,排序的部分和上面直插排序完全一致。

    #include <stdio.h> 
    #include <windows.h>
    int main()
    {
        int a[10] = { 123, 34, 76, 31, 678, 94, 456, 29, 4, 23 };
        int d;                    //每次排序的间隔值
        int x = 0;                //中间变量
        int n = 10;                //数组长度
        d = n / 2;                //初始间隔为数组长度的一半
        while (d >= 1)            //当间隔为1的时候,使用一次插入排序
        {
            for (int i = d; i < n; i++)
            {
                x = a[i];
                int j = i - d;
                while (j >= 0 && a[j]>x)        //使用a[j]和a[i]作为一对去排序
                {
                    a[i] = a[j];
                    j = j - d;
                }
                a[j + d] = x;
            }
            d = d / 2;
            for (int k = 0; k < 10; k++){ printf("%d	", a[k]); }printf("
    ");
        }
    }

      

     四、快速排序

    第一步,选择一个数作为基准(本例中选择数组最前端那个)

    第二步,将后面的所有数字里面,比基数小的放左边,比基数大的放右边

    第三步,不断重复第二步。。。

    本例中使用左右指针。

    #include <stdio.h>
    void change(int *a, int *b);
    void Sequence(int a[], int q, int p);
    
    int main()
    {
        int a[10] = { 12, 13, 15, 20, 0, -1, -10, 100 ,13 ,1};
        Sequence(a, 0, 9);
        for (int k = 0; k < 10; k++){ printf("%d	", a[k]); }printf("
    ");
    }
    
    /*互换位置
    */
    void change(int *a, int *b)
    {
        int temp = *a;
        *a = *b;
        *b = temp;
    }
    
    /*快速排序函数
    参数说明:
    a[]        待排数组
    q        左指针的位置
    p        右指针的位置
    */
    void Sequence(int a[], int q, int p)
    {
        int q_1 = q;//q一开始的位置
        int p_1 = p;//p一开始的位置
        int basis = a[q];//基准数据 取数组的第一个数
        //当左右指针相遇时不循环了,此时q=基数所应该在的位置
        if (q >= p){ return; }
    
        while (q < p)
        {
            //先走p
            //a[p]和基数比较,如果比基数大,指针向前挪动,如果比基数小,则和a[q]换位
            while (q < p && a[p] > basis)
            {
                p--;
            }
            change(&a[q], &a[p]);
            q++;
    
            //a[q]和基数比较,只要a[q]比基数小,就往右走,直到走到比基数大的数,就和a[p]换位
            while (q < p && a[q] < basis)
            {
                q++;
            }
            change(&a[q], &a[p]);
            p--;
        }
        a[q] = basis;//将最开始选定的基数,赋值给q指针最后指向的地方,也就是basis本应在的位置
    
        /*
        到这里,第一次循环已经结束了,但是还需要对左右两个大小数组各进行快排
        所以,这两个数组,{0→q-1},{q+1→p}还需要再用同样的方法进行排序
        */
    
        //此时,q已经是基准数basis所在的位置了,利用一开始存的变量区域放进函数
        Sequence(a, q_1, q - 1);
        Sequence(a, q + 1, p_1);
    
    }
    123, 34, 76, 31, 678, 94, 456, 29, 4, 23
  • 相关阅读:
    day05 集合
    day05 判断敏感字符
    day05 None类型
    day05 字典
    day04元组
    day04列表
    HDFS配额管理(实战)
    hive数据库的哪些函数操作是否走MR
    oracle 裸设备划分 --centos6.5
    redis3.0.7集群部署手册
  • 原文地址:https://www.cnblogs.com/qifeng1024/p/11724223.html
Copyright © 2011-2022 走看看