选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理是每一次从待排序的数据元素中选出最小(或最大)的一个元素,存放待排序序列的起始位置(或末尾位置),直到全部待排序的数据元素排完。
由于选择排序一次能确定一个元素的位置,所以选择排序需要循环size-1次。
算法的稳定性: 不稳定 (比如序列【5, 5*, 3】第一趟就将第一个[5]与[3]交换,导致第一个5挪动到第二个5*后面)
时间复杂度: O(n^2);
空间复杂度: O(1)-------没有借助辅助空间;
代码实现:
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
//选择排序
void SelectSort(int *array, int size);
//打印
void Print(int *array, int size)
{
int i = 0;
for (i = 0; i < size; i++)
{
printf("%d ", array[i]);
}
printf("\n");
}
void swap(int *x, int *y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
//选择排序(一次将一个数据放到它最终的位置上)
void SelectSort(int *array, int size)
{
//最大值下标
int maxpos = 0;
int i = 0;
int j = 0;
//循环size-1次
for (i = 0; i < size-1; i++)
{
maxpos = 0;
//找出最大值下标
for (j = 1; j < size-i; j++)
{
if (array[j]>array[maxpos])
{
maxpos = j;
}
}
//将最大值插入
if (maxpos != size - i - 1)
{
swap(&array[maxpos], &array[size - i - 1]);
}
}
}
测试文件:
#include"sort.h"
void TestSelectSort()
{
int array[] = { 10, 2, 5, 4, 6, 9, 3, 1, 0 };
printf("排序前:");
//打印
Print(array, sizeof(array) / sizeof(array[0]));
//选择排序
//SelectSort(array, sizeof(array) / sizeof(array[0]));
printf("排序后:");
//打印
Print(array, sizeof(array) / sizeof(array[0]));
}
int main()
{
TestSelectSort();
system("pause");
return 0;
}
选择排序是一次确定一个元素的位置,而选择排序的优化则是一次确定两个元素的位置,比如降序:每次将最小值放在起始位置,最大值放在末尾位置。
代码实现:
//选择排序的优化(一次将两个元素放在它的最终位置上)
void SelectSortOP(int *array, int size)
{
//最小值下标
int minpos = 0;
//最大值下标
int maxpos = 0;
int left = 0;
int right = size - 1;
int j = 0;
//循环size-1次
while (left < right)
{
maxpos = left;
minpos = left;
//确定最大值下标以及最小值下标
for (j = left; j <= right; j++)
{
if (array[j]>array[maxpos])
{
maxpos = j;
}
if (array[j] < array[minpos])
{
minpos = j;
}
}
//将最大值插到最后
if (maxpos != right)
{
swap(&array[maxpos], &array[right]);
}
//防止minpos在最大值要插入的位置
if (minpos == right)
{
minpos = maxpos;
}
//将最小值插到最前面
if (minpos != left)
{
swap(&array[minpos], &array[left]);
}
left++;
right--;
}
}
为什么要写下面这块代码:
if (minpos == right)
{
minpos = maxpos;
}
比如序列【10, 2 ,4,6 ,0】maxpos=0,minpos=4;
maxpos!=4,交换0和10【0, 2 ,4,6 ,10】但是maxpos依旧是0,minpos依旧是4,minpos!=0,又再次交换0和10.
所以为防止minpos在最大值要插入的位置,要加上上面这块代码。