zoukankan      html  css  js  c++  java
  • 对冒泡排序法的个人理解

    下文全部以数组的从小到大排序为例,对象排序、从大到小排序同理。

    冒泡排序法,是从数组的第一个数开始,依次向后比较相邻的两个数;前者比较大时,就将二者换位,这样一次遍历完成后,最大的数就在最后;之后再从第一个数开始向后比较(不比较最后一个数),依此类推。

    选择排序法,是用数组的第一个数,依次和后面的数比较;后面的数小于第一个数时,将其置换到第一位,这样一次遍历完成后,第一个数就是最小的数;之后再从第二个数开始和后面比较,依此类推。

    以前写冒泡排序法时,都是写完两个循环之后,用第一次外循环和最后一次外循环时比较的数组角标,来计算两个循环的初始值和条件表达式。今天觉得每次都要算一下这个好麻烦,然后想了想外循环和内循环的意义:

     1   for(i = 0; i < N-1; i++) {//内循环进行次数:数组长度-1
     2     //内循环:一次冒泡,循环完成后数组最后一个数是最大的数
     3     for(j = 0; j < N-i-1; j++) {//比较进行次数:数组长度-已完成排序数量-1(已完成排序数量=内循环已完成次数=i)
     4       if(buf[j] > buf[j+1]) {
     5         temp = buf[j];
     6         buf[j] = buf[j+1];
     7         buf[j+1] = temp;
     8       }
     9     }
    10   }

    每次内循环完成后,数组最后一个数就是最大的数,因此一共需要进行(数组长度-1)次内循环,所以外循环的条件表达式为 i<N-1 

    每次内循环中,需要比较的次数为剩余需要排序的数量-1次(最后一个数不需要和后面的数比较);又因剩余需要排序的数量=数组长度-已完成排序的数量,而已完成排序的数量=内循环完成次数,所以每次内循环需要进行(数组长度-内循环已完成次数-1)次比较,所以内循环的条件表达式为 j<N-i-1 。

    这样理解就简单多了。

    同时,也可以据此计算出一次冒泡排序法需要比较的次数:N(N-1)/2次。(N-i-1(i从0到N-2)的累加和)。

    总结一下:

    对于外循环,我们只关心内循环需要进行的次数,也就是把最大的数放到最后这个操作重复的次数(N-1次),因此外循环为 for(i = 0; i < N-1; i++) ;

    对于内循环,我们只关心每次内循环比较的次数,也就是每次把最大的数放到最后需要比较的次数(N-i-1次),因此内循环为 for(j = 0; j < N-i-1; j++) ;

    至于是从小到大排序,还是从大到小排序,这些事情就交给比较环节去改变就可以了。

    同样的,对于选择排序法,有:

    外循环需要从第一个数向后遍历,直到倒数第二个数,因此一共需要进行(数组长度-1)次内循环,所以外循环的条件表达式为 i<N-1 ,外循环为 for(i = 0; i < N-1; i++) ;

    每次内循环中,已完成排序数量为i,而每次内循环都是从当前还没完成排序的第一个数,向后遍历到数组结尾,因此内循环为 for(j = i; j < N-1; j++) 。

    同时,也可以据此计算出一次选择排序法需要比较的次数:N(N-1)/2次。(N-i-1(i从0到N-2)的累加和)。

  • 相关阅读:
    AC自动机【学习笔记】
    SCOI2016 背单词【Trie树,贪心】
    【字符串算法】字典树Trie入门
    USACO 1.3 Name That Number【暴搜】
    MapReduce分组
    MapReduce排序
    博客园添加访问人数统计
    MapReduce的分区
    MapReduce的计数器
    MapReduce部分源码解读(一)
  • 原文地址:https://www.cnblogs.com/cage666/p/10648767.html
Copyright © 2011-2022 走看看