简单选择排序
简单选择排序(Simple Selection Sort)也称作直接选择排序。
算法思路
[算法步骤]
① 设待排序的记录窜访在数组r[1…n]中。第一趟从r[1]开始,通过n-1次比较,从n个记录中选出关键字最小的记录,记为r[k],交换r[1]和r[k]。
② 第二趟从r[2] 开始,通过n-2次比较,从n-1个记录中选出关键字最小的记录,记为r[k],交换r[2]和r[k]。
③ 依次类推,第i趟从r[i]开始,通过n-i次比较,从n-i+1个记录中选出关键字最小的记录,以为r[k],交换r[i]和r[k]。
④ 经过n-1趟,排序完成。
算法实现
定义存放记录的线性表结构
//记录
typedef struct ElemType{
int key;
string info;
}ElemType;
#define InitSize 50
typedef struct {
ElemType data[InitSize];
int length;
}SqList;
void toString(SqList L);
void toString(SqList L,int low,int high);
void InitSqList(SqList &L);
代码实现
void SelectSort(SqList &L) {
ElemType min = L.data[0];
for (int i = 0; i < L.length-1; i++) {
int k = i;
cout << " -----------------第" << k+1 << "趟排序--------------------- "
<< endl;
cout << "初始min r["<< k <<"]= " << L.data[k].key
<< endl;
for (int j = i + 1; j < L.length; j++) {
if (L.data[j].key < L.data[k].key) {
k = j;
cout << "新的min r["<< k <<"]= " << L.data[k].key << endl;
}
}
if (k != i) {
swap(L.data[i], L.data[k]);
}
cout << "有序 " ;
toString(L,0,i);
cout << "待排序 " ;
toString(L,i+1,L.length-1);
}
}
测试案例
void testSelectSort(){
SqList L;
InitSqList0(L);
cout <<" ----------------------------初始 L----------------------------------"<< endl;
toString(L,0,L.length-1);
SelectSort(L);
cout <<" -------------------------最终排序结果--------------------------------"<< endl;
toString(L,0,L.length-1);
}
int main() {
testSelectSort();
return 0;
}
测试结果
----------------------------------初始 L----------------------------------------
[ 41 67 34 0 69 24 78 58 62 64 ]
-----------------------------------第1趟排序---------------------------------------
初始min r[0]= 41
新的min r[2]= 34
新的min r[3]= 0
有序 [ 0 ]
待排序 [ 67 34 41 69 24 78 58 62 64 ]
-----------------------------------第2趟排序---------------------------------------
初始min r[1]= 67
新的min r[2]= 34
新的min r[5]= 24
有序 [ 0 24 ]
待排序 [ 34 41 69 67 78 58 62 64 ]
-----------------------------------第3趟排序---------------------------------------
初始min r[2]= 34
有序 [ 0 24 34 ]
待排序 [ 41 69 67 78 58 62 64 ]
-----------------------------------第4趟排序---------------------------------------
初始min r[3]= 41
有序 [ 0 24 34 41 ]
待排序 [ 69 67 78 58 62 64 ]
-----------------------------------第5趟排序---------------------------------------
初始min r[4]= 69
新的min r[5]= 67
新的min r[7]= 58
有序 [ 0 24 34 41 58 ]
待排序 [ 67 78 69 62 64 ]
-----------------------------------第6趟排序---------------------------------------
初始min r[5]= 67
新的min r[8]= 62
有序 [ 0 24 34 41 58 62 ]
待排序 [ 78 69 67 64 ]
-----------------------------------第7趟排序---------------------------------------
初始min r[6]= 78
新的min r[7]= 69
新的min r[8]= 67
新的min r[9]= 64
有序 [ 0 24 34 41 58 62 64 ]
待排序 [ 69 67 78 ]
-----------------------------------第8趟排序---------------------------------------
初始min r[7]= 69
新的min r[8]= 67
有序 [ 0 24 34 41 58 62 64 67 ]
待排序 [ 69 78 ]
-----------------------------------第9趟排序---------------------------------------
初始min r[8]= 69
有序 [ 0 24 34 41 58 62 64 67 69 ]
待排序 [ 78 ]
-------------------------------最终排序结果--------------------------------------
[ 0 24 34 41 58 62 64 67 69 78 ]
进程已结束,退出代码0
算法分析
① 时间复杂度:
简单选择排序过程中,所需进行记录移动次数较少。
- 最好情况(正序):不移动;
- 最坏情况(逆序):移动3(n-1)次。
然而,无论记录的初始排序如何,所需进行的关键字间的比较次数相同,均为
KCN=(n-1)+(n-2)+…+(3-1)+(2-1)=n(n-1)/2
因此,简单选择排序的时间复杂度为O(n^2/2)。
② 空间复杂度
同冒泡排序一样,只有在两个记录交换时需要一个辅助空间,所以空间复杂度为O(1)。
[算法特点]
① 本身时稳定的排序方法,采用”交换记录“的策略会产生不稳定的现象。
② 可用于链式结构。
③ 移动记录次数较少,当每一项记录占用空间较大时,简单选择排序比直接插入排序快。