排序算法(四)选择排序及优化版本

在前边的排序算法(一)中已经分析过选择排序,这里主要是想讲解他的优化版本。
选择排序,是通过每次选择最小的数或者最大的数,然后将它放在它应该出现的位置上。
具体实现过程:将0号下标的数据保存,在之后的数中选择一个最小的数,如果最小的数不是0号数,则将最小的数与0号下标的数进行交换;将1号下标的数进行保存,在之后的数中 选择最小的数,如果最小的数不是1号数,进行交换。以此类推。
下边给出实现代码:

void SelectSort(vector<int>& v)
{
    for(int i = 0; i < v.size() - 2; ++i)
    {
        int k = i;
        for(int j = i + 1; j < v.size() - 1; ++j)
        {
            //找到最小的数的下标
            if(v[j] < v[k])
                k = j;
        }
        if(k != i)
        {
            swap(v[k],v[i]);
        }
    }
}

这样一来,对于每一趟,我们需要遍历一遍,将找到的最小的数放在应该出现的位置,所以,选择排序的时间复杂度是O(N*N),不管是最好情况还是最坏情况,找最小数的过程都需要遍历一遍,所以,选择排序最好情况也是O(N*N)。
优化版本:
根据上边的分析,如果在每一次查找最小值的时候,也可以找到一个最大值,然后将两者分别放在它们应该出现的位置,这样遍历的次数就比较少了,下边给出代码实现:

void SelectSort(vector<int>& a)
{
    int left = 0;
    int right = a.size() - 1;
    int min = left;//存储最小值的下标
    int max = left;//存储最大值的下标
    while(left <= right)
    {
        min = left;
        max = left;
        for(int i = left; i <= right; ++i)
        {
            if(a[i] < a[min])
            {
                min = i;
            }
            if(a[i] > a[max])
            {
                max = i;
            }
        }
        swap(a[left],a[min]);
        if(left == max)
            max = min;
        swap(a[right],a[max]);

        ++left;
        --right;
    }
}

这样总共遍历的次数比起前边的一般版本就会减少一半,时间复杂度是O(N/2 * N /2)还是O(N*N)。但是,代码中,第一次交换结束后,如果left那个位置原本放置的就是最大数,交换之后,需要将最大数的下标还原。
需要注意的是,每次记住的最小值或者最大值的下标,这样方便进行交换。

    原文作者:排序算法
    原文地址: https://blog.csdn.net/peiyao456/article/details/53240482
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞