排序算法小结(冒泡排序、简单选择排序、快速排序)

排序算法小结(冒泡排序、简单选择排序、快速排序)

    1)冒泡排序bubble_sort
        1.原理
            假设对a[N]进行排序
            依次比较相邻两个数,小数放前,大数放前。
            *1    从头开始进行第一轮比较,则得到最后一个位置是所有数中的最大的一个数;       
                需要比较的次数是N-1,为什么是N-1?因为,总共是N个数,数组下标是从0开始,
                如果比较最后两个数据,判断条件:if(a[N-1-1] > a[N-1]),a[N-1]就是数组的最后一个数了,
                如果比较次数是N,则执行该论最后一对数据比较时就是if(a[N-1] > a[N]),
                众所都知,a[N]中是没有a[N],所以次数会得到一个意想不到的排序,里面会多一个垃圾值,垃圾值的产生就是a[N]。
                所以此时必须用N-1。
            *2    从头开始进行第二轮比较,则得到倒数第二个位置是所有数中的次最大数;       
                需要比较的次数是(N-1)-1,为什么是(N-1)-1?因为,解释同上。
            *3    从头依次进行第三轮比较,则得到倒数第三个位置是所有数中的次次最大数;       
                需要比较的次数是N-1-1-1,为什么是(N-1)-1-1?因为,解释同上。
            *N-1    依次从头开始比较,直至比较完。
        2.代码实现过程
            void bubble_sort(int a[], int N)            //N是数组a的长度
            {
                int i, j, tmp;

                for(i = 0; i < N-1; i++)            //进行比比较的趟数,此时的N-1如果换成N,对程序影响不大,只不过多一次循环而已
                {
                    for(j = 0; j < N-i-1; j++)        //开始进行比较,此时的N-i-1不能换成N-i,如果写成N-i,会产生一个垃圾值,解释在*1中
                    {
                        if(a[j] > a[j+1])
                        {
                            tmp    = a[j];
                            a[j]   = a[j+1];
                            a[j+1] = tmp;
                        }
                    }
                }
               
                return;
            }
   
    2)简单选择排序select_sort
        1.原理
            假设对a[N]进行排序
            假定选一个最小的,依次把后面的数与它进行比较,如果后面的比假定选的最小的还小,则进行交换这两个数。每进行一轮就要找出一个最小的数。
            *1    第一轮    假定第一个数是“最小的”,然后依次把后面的数与这个“最小的”的进行比较,如果比这个“最小的”小,首先标记该数为“最小的”,
                    然后把这个“最小的”与前面的“最小的”交换值,目的是保证第一个数是后面所有数中最小的一个。
            *2    第二轮    因为已经知道第一个是最小的,这时从第二个开始寻找最小的,假定第二个是最小的,然后依次把后面的数与这个“最小的”的进行比较,
                    如果比这个“最小的”小,首先标记该数为“最小的”,然后把这个“最小的”与前面的“最小的”交换值,目的是保证第二个数是后面所有数中最小的一个。

            *N    第N轮    步骤同上。
           
            说明    是进行N轮比较还是N-1轮比较,影响不大,原因是:该数组中共有N个数,如果对N-1个数进行了排序处理,即第N-1个数是后面中最小的一个数,
                剩余的唯一的第N个数肯定是所有数中最大的,显然它应该放在最后一个位置上,没必要再进行一次循环。如果是进行N轮比较,无非是程序多执行一次循环,
                其实实际上这次循环也没有执行,因为在子循环中无法满足循环条件,不能执行循环体。

        2.代码实现过程
            void select_sort(int a[], int N)        //N是数组a的长度
            {
                int i, j, min, tmp;

                for(i = 0; i < N; i++)            //从头开始比较
                {
                    min = i;            //把第i个数当作最小的,把下标标记为min
                    for(j = i+1; j < N; j++)    //把a[min]依次和它后面的数进行比较
                    {
                        if(a[j] < a[min])    //如果后面的某个值比a[min]小
                        {
                            min = j;    //重新标记最小值下标
                        }
                        tmp = a[min];        //交换
                        a[min] = a[i];        //原来min = i的,如果没有找到比a[min]小的,就不进行交换(如果没找到,i还是和min一样,执行该三条语句没作用)
                        a[i] = tmp;        //只有a[j] < a[min]成立,执行了min = j,这时才能交换(这时min的已经改为j,不再是i了,所以执行才有作用)
                    }                //自己表达欠缺,上面三句表达不够明确,只要自己研读程序,因该能明白其中奥妙
                }

                return;
            }

    3)快速排序quick_sort
        1.原理
            假定对a[N]排序
            快速排序使用分治法(Divide and conquer)策略来把一个序列(list)分为两个子序列(sub-lists)。
            实现快速排序需要两个函数,分别是:partition()和quick_sort()
           
            函数:            int partition(int a[], int i, int j)
            函数功能:        把数组分为两段,左段都是比基准小的数,但是左段的数是无序的;右段都是比基准大的数,但是右段的数是无序的。
            函数大概实现过程:       
                    *1    选取一个基准(pivot),基准一般选取第一个数a[0];

                    *2    定义两个变量i、j;
                        令j从数组尾部向左扫描,直到遇到一个数比基准小的,进行交换。目的是:使比基准小的都放在基准左边。
                        令i从数组开头向右扫描,直到遇到一个数比基准大的,进行交换。目的是:使比基准大的都放在基准右边。
                        进行多次循环后,最终i的值就是基准应该放的位置。
                        原因是:我们假定的基准是数组的第一个数a[0],a[0]也许既不是数组中最大的数也不是数组中最小的数,
                        也就是基准的位置应该在数组中的某个位置,经过多次循环后,i不断往后递增,当不满足循环条件时,i就停止了,此时i就是基准的位置
                        (表达欠缺,还需要自己揣摩)
               
            函数:            void quick_sort(int a[], int left, int right)
            函数功能:        实现排序
            函数大概实现过程:
                        递归的对每一段进行排序

        2.代码实现过程
            int partition(int a[], int i, int j)
            {           
                int pivot;                //基准
       
                pivot = a[i];               
                while(i < j)
                {
                    while(i < j && a[j] > pivot);   
                    {
                        j--;            //如果右边的比基准大,左移j
                    }
                    a[i] = a[j];            //如果遇到了右边的比基准小,和基准交换
               
                    while(i < j && pivot <= a[i]);
                    {
                        i++;            //如果左边的基准小,右移i
                    }
                    a[j] = a[i];            //如果遇到了左边的比基准大,和基准交换
                }
                a[i] = pivot;

                return i;
            }

            void quick_sort(int a[], int left, int right)
            {
                int pivottag;
           
                if(left < right)
                {
                    pivottag = partition(a, left, right);
                    quick_sort(a, 0, pivottag-1);   
                    quick_sort(a, pivottag+1, right);
                }

                return;
            }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值