目录
和冒泡排序区别:冒泡排序是逐步对相邻元素进行操作(比较和交换位置)。而选择排序是从待排序数列中选择最大/小值,再将之放置到已排序数列中。
(有序区,无序区)。在无序区里找一个最小的元素跟在有序区后面。对数组:比较的多,换的少。
选择排序思路:
1、在未排序序列中找到最小(大)元素,存放到排序序列起始位置。
2、从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列末尾。
3、以此类推,直到所有元素均排序完毕。
一、普通实现
void SelectionSort(vector<int> &v)
{
int min, len = v.size();
for (int i = 0; i < len - 1; i++)
{
min = i;
for (int j = i + 1; j < len; j++)
{
if (v[j] < v[min]) // 标记最小的
{
min = j;
}
}
if (i != min) // 交换到前面
{
swap(v[i], v[min])
}
}
}
二、模板实现
template<typename T>
void SelectionSort(vector<T> &arr)
{
int len = arr.size();
for (int i = 0; i < len - 1; i++)
{
int min = i;
for (int j = i + 1; j < len; j++)
{
if (arr[j] < arr[min])
{
min = j;
}
}
if (i != min)
{
swap(arr[i], arr[min]);
}
}
}
三、优化版本一
一次就选出最小值和最大值
template<typename T>
void Selection(T *arr, int n)
{
assert(arr);
int left = 0;
int right = n - 1;
while (left < right)
{
int min = left;
int max = right;
for (int i = left; i <= right; i++)
{
if (arr[i] < arr[min])
min = i;
if (arr[i] > arr[max])
max = i;
}
// 考虑修正的情况,最大值在最小位置,最小值在最大位置
swap(arr[max], arr[right]);
if (min == right)
min = max;
swap(arr[min], arr[left]);
left++;
right--;
}
}
四、优化版本二
void SelectionSort(vector<int> &v)
{
int len = v.size();
for (int left = 0, right = len - 1; left < right; left++, right--)
{
int min = left; // 记录最小值
int max = right; // 记录最大值
for (int index = left; index <= right; index++)
{
if (v[index] < v[min])
min = index;
if (v[index] > v[max])
max = index;
}
// 最小值交换
swap(v[min], v[left]);
// 此处是先排最小值的位置,所以得考虑最大值在最小位置的情况
if (left == max)
{
max = min;
}
swap(v[max], v[right]);
}
}