1. 选择排序
基本思想:每一趟均对数组未排序区间进行排序,将未排序区间的第一个元素与未排序区间的其他元素一一比较,最后未排序区间中最大或最小的元素交换到未排序区间的第一个元素处。相当于打擂台比赛!
举例说明:待排序数组array[7]={6,4,8,1,9,2,3},以升序的方式进行排序。
需要先定义一个边界bound区分待排序与已排序区间,[0,bound)表示已排序区间,[bound,size)表示待排序区间。定义一个索引cur用于探测待排序区间中的元素。类似于打擂台的形式的话,开始打擂台时擂主为bound_value=array[bound],参赛者cur为待排序的元素,即从下标bound+1到size-1的元素。比赛规则为:谁最小谁赢。
(1)第一趟排序:边界bound初始为0,故待排序区间[bound,size)为[0,size),待排序数组array[7]={6,4,8,1,9,2,3},此时的擂主为:bound_value=array[bound]=array[0]=6,开始打擂台。参赛者cur为待排序的元素,即从下标bound+1到size-1的元素。
开始第一趟的比较(比较条件为bound<cur<size=7):
①cur=bound+1=1,擂主bound_value=6,擂主>array[cur]=4,则擂主输,交换两个元素的值,数组变为array[7]={4,6,8,1,9,2,3},擂主bound_value变为4。
②cur++即cur=2,擂主bound_value=4,擂主<array[cur]=8,则擂主赢,不交换两个元素的值,数组仍为array[7]={4,6,8,1,9,2,3},擂主bound_value仍为4。
③cur++即cur=3,擂主bound_value=4,擂主>array[cur]=1,则擂主输,交换两个元素的值,数组变为array[7]={1,6,8,4,9,2,3},擂主bound_value变为1。
④cur++即cur=4,擂主bound_value=1,擂主<array[cur]=9,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,6,8,4,9,2,3},擂主bound_value仍为1。
⑤cur++即cur=5,擂主bound_value=1,擂主<array[cur]=2,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,6,8,4,9,2,3},擂主bound_value仍为1。
⑥cur++即cur=6,擂主bound_value=1,擂主<array[cur]=3,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,6,8,4,9,2,3},擂主bound_value仍为1。
⑦cur++即cur=7,而cur!<size=7,故第一趟比较结束。此时待排序区间的最小值1来到了边界bound处。
(2)第二趟排序:边界bound变为1,故待排序区间[bound,size)为[1,size),待排序数组array[7]={1,6,8,4,9,2,3};此时的擂主为:bound_value=array[bound]=array[1]=6,开始打擂台。参赛者cur为待排序的元素,即从下标bound+1到size-1的元素。
开始第二趟的比较(比较条件为bound<cur<size=7):
①cur=bound+1=2,擂主bound_value=6,擂主<array[cur]=8,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,6,8,4,9,2,3};擂主bound_value仍为6。
②cur++即cur=3,擂主bound_value=6,擂主>array[cur]=4,则擂主输,交换两个元素的值,数组变为array[7]={1,4,8,6,9,2,3},擂主bound_value变为4。
③cur++即cur=4,擂主bound_value=4,擂主<array[cur]=9,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,4,8,6,9,2,3},擂主bound_value仍为4。
④cur++即cur=5,擂主bound_value=4,擂主>array[cur]=2,则擂主输,交换两个元素的值,数组变为array[7]={1,2,8,6,9,4,3},擂主bound_value变为2。
⑤cur++即cur=6,擂主bound_value=2,擂主<array[cur]=3,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,2,8,6,9,4,3},擂主bound_value仍为2。
⑥cur++即cur=7,而cur!<size=7,故第二趟比较结束。此时待排序区间的最小值2来到了边界bound处。
(3)第三趟排序:边界bound变为2,故待排序区间[bound,size)为[2,size),待排序数组array[7]={1,2,8,6,9,4,3};此时的擂主为:bound_value=array[bound]=array[2]=8,开始打擂台。参赛者cur为待排序的元素,即从下标bound+1到size-1的元素。
开始第三趟的比较(比较条件为bound<cur<size=7):
①cur=bound+1=3,擂主bound_value=8,擂主>array[cur]=6,则擂主输,交换两个元素的值,数组变为array[7]={1,2,6,8,9,4,3};擂主bound_value变为6。
②cur++即cur=4,擂主bound_value=6,擂主<array[cur]=9,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,2,6,8,9,4,3},擂主bound_value仍为6。
③cur++即cur=5,擂主bound_value=6,擂主>array[cur]=4,则擂主输,交换两个元素的值,数组变为array[7]={1,2,4,8,9,6,3},擂主bound_value变为4。
④cur++即cur=6,擂主bound_value=4,擂主>array[cur]=3,则擂主输,交换两个元素的值,数组变为array[7]={1,2,3,8,9,6,4},擂主bound_value变为3。
⑤cur++即cur=7,而cur!<size=7,故第三趟比较结束。此时待排序区间的最小值3来到了边界bound处。
(4)第四趟排序:边界bound变为3,故待排序区间[bound,size)为[3,size),待排序数组array[7]={1,2,3,8,9,6,4};此时的擂主为:bound_value=array[bound]=array[3]=8,开始打擂台。参赛者cur为待排序的元素,即从下标bound+1到size-1的元素。
开始第四趟的比较(比较条件为bound<cur<size=7):
①cur=bound+1=4,擂主bound_value=8,擂主<array[cur]=9,则擂主赢,不交换两个元素的值,数组仍为array[7]={1,2,3,8,9,6,4};擂主bound_value仍为8。
②cur++即cur=5,擂主bound_value=8,擂主>array[cur]=6,则擂主输,交换两个元素的值,数组变为array[7]={1,2,3,6,9,8,4},擂主bound_value变为6。
③cur++即cur=6,擂主bound_value=6,擂主>array[cur]=4,则擂主输,交换两个元素的值,数组变为array[7]={1,2,3,4,9,8,6},擂主bound_value变为4。
④cur++即cur=7,而cur!<size=7,故第四趟比较结束。此时待排序区间的最小值4来到了边界bound处。
(5)第五趟排序:边界bound变为4,故待排序区间[bound,size)为[4,size),待排序数组array[7]={1,2,3,4,9,8,6};此时的擂主为:bound_value=array[bound]=array[4]=9,开始打擂台。参赛者cur为待排序的元素,即从下标bound+1到size-1的元素。
开始第五趟的比较(比较条件为bound<cur<size=7):
①cur=bound+1=5,擂主bound_value=9,擂主>array[cur]=8,则擂主输,交换两个元素的值,数组变为array[7]={1,2,3,4,8,9,6};擂主bound_value变为8。
②cur++即cur=6,擂主bound_value=8,擂主>array[cur]=6,则擂主输,交换两个元素的值,数组变为array[7]={1,2,3,4,6,9,8},擂主bound_value变为6。
③cur++即cur=7,而cur!<size=7,故第五趟比较结束。此时待排序区间的最小值6来到了边界bound处。
(6)第六趟排序:边界bound变为5,故待排序区间[bound,size)为[5,size),待排序数组array[7]={1,2,3,4,6,9,8};此时的擂主为:bound_value=array[bound]=array[5]=9,开始打擂台。参赛者cur为待排序的元素,即从下标bound+1到size-1的元素。
开始第六趟的比较(比较条件为bound<cur<size=7):
①cur=bound+1=6,擂主bound_value=9,擂主>array[cur]=8,则擂主输,交换两个元素的值,数组变为array[7]={1,2,3,4,6,8,9};擂主bound_value变为8。
②cur++即cur=7,而cur!<size=7,故第六趟比较结束。此时待排序区间的最小值8来到了边界bound处。
此时,打擂台比赛结束,数组变成了有序数组。
代码实现如下:
//0.交换两个数的值
void Swap(int* x,int* y)
{
int tmp=*x;
*x=*y;
*y=tmp;
}
void SelectSort(int array[],size_t size)
{
//当size<=1时,不需要排序直接return
if(size<=1)
return;
//定义一个边界bound,[0,bound)表示有序区间 [bound,size)表示无序区间
size_t bound=0;
for(;bound<size;bound++)
{
size_t cur=bound+1;
for(;cur<size;cur++)
{
//类似于打擂台
if(array[bound]>array[cur])
{
Swap(&array[bound],&array[cur]);
}
}
}
}