1. 选择排序理解
选择排序通俗来说,就是从左到右把左边的数字依次和右边每一个数字做比较,得出整个数组的最小值,将其放置最左侧;随后,将左边第二个开始和右边比,得出次小值…最后排序完毕
2. 举例解释
现在有一数组,内容为:6 5 8 9 1 3 4 7,其下角标为:0 1 2 3 4 5 6 7
统一这样写数组及其角标
原数组:
6 5 8 9 1 3 4 7
0 1 2 3 4 5 6 7
第一步:
将第0位与后面所有元素比较,哪个元素小就将该元素与第0位元素交换,最终第0位元素是整个数组中的最小值
1|| 5 8 9 6 3 4 7
0 1 2 3 4 5 6 7
此后,第0位的值不变,因为该位已经是最小值了,下一步是从第1步开始上述步骤,目标是将次最小值放到第1位
第二步:
第0位的值不变,因为该位已经是最小值了,下一步是从第1步开始上述步骤,目标是将次最小值放到第1位
1 3|| 8 9 6 5 4 7
0 1 2 3 4 5 6 7
以此重复直到最后一次比较,即末位和次末位比较,比较完后结束,得出正确排序
3 程序思路
第一轮是要把第0位与所有数比较,共计比较N-1次;第二轮是第1位与后续所有比较,共计N-2轮…我们可以发现:
每次比较一轮(外层循环),放最小值的位会往后挪(内侧循环控制)
考虑双重循环,外循环i=0,i<N-1【N-1是因为下标比数组实际长度要小1,另外,其实只要重复N-2次,比如数组是三位,但是只需要比较两次,而下标是0-2,那么比较两次就是0-1,于是是<2,不能包括2,即<N-1,不包括N-1】
内层循环就是来依次比较数组元素大小,将j=i+1,j<N;j=i+1是因为要将第i位与其后面相比较,j<N是因为要比较的次数是N-1次
程序:
class Program
{
static void Main(string[] args)
{
int[] t= { 3, 2, 1, 7, 8, 9, 0 };
Swap.GetSelectionSort(t);//排序
Swap.StartPrint(t);//打印排序后的数组内容
Console.ReadLine();
}
}
static class Swap
{
//从小到大排序
//选择排序是指第一次排序时把最小的数放到数组0位,然后在数组1位和n位进行选择,把最小的数放1位,以此类推
public static void GetSelectionSort(int[] arr)
{
if (arr==null&&arr.Length<=2)
{
return;
}
for (int i = 0; i < arr.Length-1; i++)//0-N-1
{
int minIndex = i;//记录最小值的下标,会随时变化,用此值来实时的采集最小值的下标
for (int j = i+1; j < arr.Length; j++)
{
minIndex = arr[minIndex] > arr[j] ? j : minIndex;//判断值,把最小值下标放在minIndex
}
Swap.StartSwap(arr, minIndex, i);//把最小值和数组某一位交换
}
}
//交换元素,注意i,j不可以相同
public static void StartSwap(int[] arr,int i,int j)
{
var t = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
//打印数组元素
public static void StartPrint(int[] arr)
{
string t="数组排序: ";
for (int i = 0; i < arr.Length; i++)
{
if (i==0)
{
t = t + arr[i];
}
else
{
t = t + "-" + arr[i];
}
}
Console.WriteLine(t);
}
4. 时间复杂度
第一次排序需要比较N-1次,第二次需要比较N-2次,第三次需要比较N-3次…
所以,所有比较次数叠加:
1+2+3+…+N-2+N-1 这是等差数列,最高次项数是N²项,所以,其时间复杂度是:O(N²)