数据结构——选择排序

本篇文章介绍数据结构与算法的经典排序算法之一:选择排序。

操作与思想

选择排序的思想和冒泡排序相似:
每次从序列剩下的元素中选出最大/最小的元素,直至整个序列有序。

和插入排序不同的是,选择排序不用进行数据的挪动,而是直接选择对应的元素进行交换。

举个例子

在插入排序中: 【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】,排序完毕。

那么程序里上述的步骤具体是如何完成的呢?

  1. 第一步:将剩余序列的第一个数看作最小值(初始条件下初始序列就是剩余序列);
  2. 第二步:开始遍历(这个例子刚好是它最小),然后【2】作为已排序的序列,剩余序列就是【5 6 3 4】;
  3. 第三步:将剩余序列的第一个元素5看作最小值;
  4. 第四步:开始遍历,发现3是剩余序列的最小值;
  5. 第五步:将3和5位置互换,此时已排序的序列为【2 3】,剩余序列为【6 5 4】;
  6. 第六步:将剩余序列的第一个元素6看作最小值;
  7. 第七步:开始遍历,发现4是剩余序列的最小值;
  8. 第八步:将6和4位置互换,此时已排序的序列为【2 3 4】,剩余序列为【5 6】;
  9. 第九步就是已排序序列为【2 3 4 5】
  10. 第十步已排序序列为 【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;	
}

敬请批评指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芣苢的成长之路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值