排序(三) 选择排序

一、选择排序

原理:

选择排序很简单,他的步骤如下:
1.从左至右遍历,找到最小(大)的元素,然后与第一个元素交换。
2.从剩余未排序元素中继续寻找最小(大)元素,然后与第二个元素进行交换。
3.以此类推,直到所有元素均排序完毕。
之所以称之为选择排序,是因为每一次遍历未排序的序列我们总是从中选择出最小的元素。

void SelectSort(vector<int>& Vector)
{
    assert(Vector.size());
    for (int i = 0; i < Vector.size() - 1; ++i)
    {
        int index = i;
        for (int j = index + 1; j < Vector.size(); ++j)
        {
            if (Vector[j] < Vector[index])
                index = j;
        }
        swap(Vector[i], Vector[index]);
    }
}

 

分析:

1.选择排序需要花费 (N – 1) + (N – 2) + … + 1 + 0 = N(N- 1) / 2 ~ N2/2次比较 和 N-1次交换操作。
2.对初始数据不敏感,不管初始的数据有没有排好序,都需要经历N2/2次比较,这对于一些原本排好序,或者近似排好序的序列来说并不具有优势。在最好的情况下,即所有的排好序,需要0次交换,最差的情况,倒序,需要N-1次交换。
3.数据交换的次数较少,如果某个元素位于正确的最终位置上,则它不会被移动。在最差情况下也只需要进行N-1次数据交换,在所有的完全依靠交换去移动元素的排序方法中,选择排序属于比较好的一种。

 

 

 

 

 

二、堆排序:

template<class T>
void _AdjustDown(T* arr, size_t size, size_t index)
{
    size_t child = index * 2 + 1;
    while (child < size)
    {
        if (child + 1 < size && arr[child + 1] > arr[child])
        {
            ++child;
        }
        if (arr[child]>arr[index])
        {
            swap(arr[child], arr[index]);
            index = child;
            child = child * 2 + 1;
        }
        else
        {
            break;
        }
    }
}

template<class T>
T* HeapSort(T* arr, size_t size)
{
    assert(arr);
    for (int i = (size - 2) / 2; i >= 0; --i)
    {
        _AdjustDown(arr, size, i);
    }
    while (size > 1)
    {
        swap(arr[0], arr[size - 1]);
        --size;
        _AdjustDown(arr, size, 0);
        return arr;
    }
}


 

posted @ 2016-05-16 10:30  _in_the_way  阅读(192)  评论(0编辑  收藏  举报