关闭

一步步地分析排序——选择排序

标签: 排序算法算法选择排序c语言java
361人阅读 评论(0) 收藏 举报
分类:

前言

本文是对《算法》第四版选择排序所做的笔记,可能因为选择排序比较基础,所以该书将其作为第一个排序算法。虽然算法本身不算复杂,但是通过一个简单算法,详细学习算法的分析过程,还是相当有意义的。本文的脉络如下:

  • 概念(对选择排序做基本介绍)
  • 代码
  • 时间成本
  • 空间成本(主要表现为是不是原地排序算法)
    现在正式进入主题。

概念

  • 什么是选择排序:首先,找到数组里最小的那个元素,然后,将它和数组里第一个元素互换位置(如果第一个元素就是最小的,很自然地,它和自己互换位置)。再然后,在剩余的元素里面,找到最小的元素,将它和第二个元素互换位置,以此类推,往复操作直到排完整个数组。这就是选择排序的概念。
  • 体验过程:来给大家推荐一个网站,点击观看排序算法动态过程:
    http://visualgo.net/sorting

代码(C语言)

书本用的Java语言,而且为了表示通用性,还写成了”Comparable”的形式,我在这里为求简洁,就用C语言来描述。算法重要的是思想,不是语言层面这些东西,而且C语言写出的选择排序,和Java没有很大的区别。代码如下:

//选择排序
void selectSort(int array[], int size)
{
    int i = 0, j = 0;
    for(; i <size; i++)
    {
        int min = i;
        for(j = i+1; j<size; j++)
        {
            if(array[j]<array[min])//(1)号语句,比较数组里的两个元素
            {
                min = j;
            }
        }
        exchange(array, min, i);//(2)号语句,互换数组里的两个元素
    }
}

//互换数组里面索引p和q的元素
void exchange(int array[], int p, int q)
{
    int t = array[p];
    array[p] = array[q];
    array[q] = t;
}

时间成本

我们用下面两个操作来表示选择排序时间成本:比较元素的次数,互换元素的次数。

  • 元素比较:如代码中(1)号语句所示,内层循环每次进行一次比较,所以元素比较次数等于内层循环执行次数。为:1+2+3+…+(N-2)+(N-1) = N(N-1)/2 = O(N²)。
  • 元素互换:如代码中(2)号语句所示,外层循环每次进行一次元素互换,所以元素互换次数等于外层循环次数。为:O(N)。
  • 结论:对于长度为N的数组,选择排序需要进行大约(N²/2)次的比较,N次数组元素的互换。则最终的时间成本为两者和,大O标记表示为:O(N²)。

空间成本

从代码看可以知道,除了互换元素额外使用常数个的(也就一个)临时变量,选择排序所有操作基本都在原数组上进行,所以选择排序是原地排序算法,空间成本不随问题规模增大而增大。

输入对时间成本的影响

由代码可以看出,外层循环,每次对剩余元素进行的遍历(扫描)都不会对下次遍历提供什么帮助。不论输入是怎样的,元素比较和互换的次数不受影响。所以,我们得出以下两点:

  • 不论输入顺序多乱(即使是完全逆序的输入),该算法也不会变得更慢。
  • 不论输入顺序多“好”(即使输入一个已经排好序的数组),算法所需时间没有丝毫减少。一个已经排好序的数组和一个完全逆序的数组,使用选择排序所消耗的时间是一样的。
  • 结论:选择排序时间成本不受输入影响。

其他特性

  • 移动元素的次数:可以看到,不论输入是怎样的,选择排序只会移动元素N次(因为只有最外层的循环才会移动数据,而最外层循环执行N次,只和数组长度有关,与输入的顺序无关)。数据移动的次数和问题规模呈线性的关系。这可能是所有排序算法里面,移动元素次数最少的一个了。
  • 选择排序不会访问当前索引左边的元素:外层循环每执行一次,都将排定一个元素,即将一个元素放在他最终的位置上面,所以,当前索引左边的元素都是已经排好序的,所以选择排序不会访问当前索引左边的元素。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:20666次
    • 积分:564
    • 等级:
    • 排名:千里之外
    • 原创:35篇
    • 转载:0篇
    • 译文:1篇
    • 评论:9条
    最新评论