八大排序(一)选择排序
主要思路
它的工作原理是每一次从待排序的数据元素中选出最大(或最小)的一个元素,存放在序列的末位置,直到全部待排序
的数据元素排完。
但是选择排序是一种不稳定的排序方法。举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么
原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。
稳定性
在这里,我们提到了一个新的概念:稳定性。
通俗地讲就是能保证排序前2个相等的数其在序列的前后位置顺序和排序后它们两个的前后位置顺序相同。
在简单形式化一下,如果Ai = Aj, Ai原来在位置前,排序后Ai还是要在Aj位置前。
例题讲解
倒序排列
eg:有一个长度n = 6的数列:9,①6,②6,13,1,22(①6,②6分别代表第一个6和第二个6,是为了解释该算法的稳定性)
第一步:首先先把9当做biggest,与后面的数比较,找到一个比9大的数就把他赋给biggest,最后发现22为最终的biggest,
就把9和22的位置调换 : 22,①6,②6,13,1,9
第二步:按照第一步进行, 结果为 :22,13,②6,①6,1,9,有上面稳定性的概念可知,虽然6=6,但第二次循环后两个6的相对
位置发生了改变,所以说他是一个不稳定的排序。
......
以此类推,直到最后排好序
因为到最后未排序的数列中一定只剩下最小数,直接放到末位即可,所以一共进行n-1次
图解: 22,①6,②6,13,1,9
22,13,②6,①6,1,9 |
22,13,9,①6,1,②6 |
22,13,9,①6,1,②6 |
22,13,9,①6,②6,1 ↓
代码实现
倒序排列
#include<stdio.h>
int arr[10000] = {0};
void SelectionSort(int*arr, int len)
{
int biggest = 0, i = 0, j = 0, site = 0, temp = 0;
for(i = 0; i < len - 1; i++)
{
//每轮循环都将未排序的数列的第一个设为biggest,并记下它的位置
biggest = arr[i];
site = i;
for(j = i + 1; j < len; j++)
{
//如果有比目前的biggest的数大的数就记下该数的位置,并更新biggest
if(arr[j] > biggest)
{
site = j;
biggest = arr[site];
}
}
//将最大数与未排序的数列的第一个调换
temp = arr[i];
arr[i] = arr[site];
arr[site] = temp;
}
}
int main()
{
int i = 0, len = 0;
printf("请输入数组长度:");
scanf("%d", &len);
printf("请输入该数列:");
for(i = 0; i < len; i++)//输入一个长度为len的数列
{
scanf("%d", &arr[i]);
}
SelectionSort(arr, len);//调用函数排序
for(i = 0; i < len; i++)//输出该数列
{
printf("%d ", arr[i]);
}
return 0;
}
正序
若要正序排列,只需把所有的biggest换为smallest,把if(arr[j] > biggest)换成
if(arr[j] < smallest)。