代码改变世界

算法与数据结构——排序(三)简单选择排序

2012-10-24 08:10  左眼微笑右眼泪  阅读(844)  评论(0编辑  收藏  举报

   我们还记得每种冒泡排序的算法吗?它的原理就是依次把每一个数与除这个数之外的其他数进行比较,然后进行交换。很显然,这个方法有一个弊病,那就是如果另外有一个数比这个数小,它们立刻交换位置,比如,如果a1与a2进行比较,发现a2比a1小,它们就进行交换,其时,这个时候根本不需要交换,因为我们是需要找到最小的数,放到最前面,而此时a2只是比a1小,我们并不能确定它就是最小的数,它还没有跟后面的a3,a4等等比较呢。应该是找到最小的数的时候,我们再进行交换。选择排序就是这样的一个原理,它和第一种冒泡排序一样,把每一个数与除这个数之外的其他数进行比较,不同的地方是,如果有比它小的,此时并不进行交换,而是把这个比它小的数的下标记到一个min字段中去,然后用这个比较小的数,去与其他的数进行比较,每一次都把比较中最小的数放到min字段中去,最后min字段中的值,就是数组中最小元素的下标了。具体流程图可以参考下面的:

image

       按照每种冒泡排序的方法,上图中标注黄色的步骤(第4,7步)是需要进行交换的,而选择排序却不进行交换,在这个时候,它只是把最小值的下标赋给了字段min,等到找到真正最小的数后,它才进行交换,也就是在第九步才进行交换,这样每次比较它只需要交换一次即可。具体代码参见下面的:

public List<int> SimpleSort(List<int> sortList)
      {
          int min;
          for (int i = 0; i < sortList.Count; i++)
          {
              min = i;
              for (int j = i + 1; j < sortList.Count; j++)
              {
                  if (sortList[min] > sortList[j])
                  {
                      min = j;
                  }
              }
              if (i != min)
              {
                  int temp = sortList[i];
                  sortList[i] = sortList[min];
                  sortList[min] = temp;
              }
          }
 
          return sortList;
      }

        我们来看这种排序算法的时间复杂度,由上面的代码,我们可以看出,选择排序交换的次数比较少,每一次比较只交换一次。在最好的情况下,比较的次数为(n-1)+(n-2)+(n-3)……3+2+1=n(n-1)/2,交换的次数为0次,在最坏的情况下,也就是逆序时,比较的次数还是(n-1)+(n-2)+(n-3)……3+2+1=n(n-1)/2次,交换的次数则为(n-1)次,也就是每次比较都交换一次。所以时间复杂度最好,最坏情况下都为O(n^n)。