本篇文章介绍数据结构与算法的经典排序算法之一:选择排序。
操作与思想
选择排序的思想和冒泡排序相似:
每次从序列剩下的元素中选出最大/最小的元素,直至整个序列有序。
和插入排序不同的是,选择排序不用进行数据的挪动,而是直接选择对应的元素进行交换。
举个例子
在插入排序中: 【2 5 6 3 4这】五个数,要把3放到2的后面,需要把4和5向右移动,4和5之间空出位置后再把3插入这个空位。
在选择排序中:【2 5 6 3 4】这五个数,确认2是最小的数后,序列剩下5 6 3 4,定位到3是序列剩下的元素中最小的,所以把3放到剩余序列的前端,也就是变成3 6 5 4,此时就是【2 3 6 5 4】。接着就是4和6互换变成【2 3 4 5 6】,排序完毕。
那么程序里上述的步骤具体是如何完成的呢?
- 第一步:将剩余序列的第一个数看作最小值(初始条件下初始序列就是剩余序列);
- 第二步:开始遍历(这个例子刚好是它最小),然后【2】作为已排序的序列,剩余序列就是【5 6 3 4】;
- 第三步:将剩余序列的第一个元素5看作最小值;
- 第四步:开始遍历,发现3是剩余序列的最小值;
- 第五步:将3和5位置互换,此时已排序的序列为【2 3】,剩余序列为【6 5 4】;
- 第六步:将剩余序列的第一个元素6看作最小值;
- 第七步:开始遍历,发现4是剩余序列的最小值;
- 第八步:将6和4位置互换,此时已排序的序列为【2 3 4】,剩余序列为【5 6】;
- 第九步就是已排序序列为【2 3 4 5】
- 第十步已排序序列为 【2 3 5 4 6】,算法排序算法运行结束。
这个算法思路和冒泡相似,都是每一次都选出最大/最小元素,把该元素放在当前剩余序列最前方,核心只在如何找到剩余序列里的那个最大/最小值而已。
核心函数
void seleteSort(int a[]){
int i,j;
int t;//本轮选择的最小元素
int ti;//最小的元素坐标
for(i=0;i<10;i++){
t = a[i];
ti = i;
for(j=i+1;j<10;j++){
if(t>a[j]){
t = a[j];
ti = j;
}
}
swap(a,i,ti);//将最值元素放置剩余序列之首
}
}
排序过程
时间复杂度
无论原来的序列怎样,始终要将每一个元素与省下的全部元素进行对比,时间复杂度O(n^2)
空间复杂度
只使用一个中间变量操作元素移动未占用其他空间,空间复杂度为O(1)。
稳定性
这是不稳定的排序算法。以刚才的例子的第二步和第三步来看:第二步首尾的0其实是初始状态尾首的0,然后第三步两个0放在一起时,第一个0其实是初始状态的最后一个0,第二个0才是初始状态的第一个0。相等的元素相对位置发生了改变,所以这是不稳定的排序算法。
完整运行代码
/*
广西师范大学 计算机科学与工程学院
GuangXi Normal University
College of Computer Science and Engineering
Student STZ
*/
#include<iostream>
#include<stdio.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
int num=6;//元素数量
void initial(int a[]){
srand((unsigned)time(NULL));//时间种子
for(int i=0;i<num;i++){
a[i] = rand()%10;//随机生成数字
}
}
void showArray(int a[]){
cout<<"Array:";
for(int i=0;i<num;i++){
cout<<a[i]<<" ";
}
cout<<endl;
cout<<"Index:";
for(int i=0;i<num;i++){
cout<<i<<" ";
}
cout<<endl<<endl;
}
void swap(int a[],int i,int j){
int t;
cout<<a[i]<<" "<<a[j]<<endl;
t = a[i];
a[i] = a[j];
a[j] = t;
}
void seleteSort(int a[]){
int i,j;
int t;//本轮选择的最小元素
int ti;//最小的元素坐标
for(i=0;i<num-1;i++){
t = a[i];
ti = i;
for(j=i+1;j<num;j++){
if(t>a[j]){
t = a[j];
ti = j;
}
}
swap(a,i,ti);//将最值元素放置剩余序列之首
showArray(a);
}
}
int main(){
int a[num];
initial(a);
cout<<"初始状态:\n";
showArray(a);
seleteSort(a);
return 0;
}
敬请批评指正