选择排序之简单选择排序

此生再无相见时 提交于 2019-11-26 06:39:27

简单选择排序

什么是简单选择排序:
简单选择排序就是在未排序的序列中,找出其中最小的元素和首位元素进行交换,
接下来在剩下的未曾进行排序的记录序列中再选出最小的元素和序列记录中的第二位置的元素进行交换,
......如此类推,就可以实现从小到大的已排序序列。
代码实现
#include<stdio.h>
void Swap(int *a, int *b);
void SimpleSelectionSort(int arr[],int length);
void PrintSort(int arr[] , int length);
int main() {
	int arr[10] = {1,9,6,7,8,9,4,8,1,4};
	SimpleSelectionSort(arr,10);
	PrintSort(arr, 10);
	return 0;
}

void Swap(int *a , int *b) {
	int temp = *a;
	*a = *b;
	*b = temp;
}

void SimpleSelectionSort(int arr[] , int length) {
	int i , j , min;
	for(i = 0 ; i < length -1 ; i ++) {
		min = i;
		for(j = i+1 ; j < length ; j++)
			if(arr[j] < arr[min])
				min = j ;
		Swap(&arr[i] , &arr[min]);
	}
}

void PrintSort(int arr[] , int length) {
	for(int i = 0 ; i < length ; i ++) {
		printf("%d\t",arr[i]);
	}
	printf("\n");
}
核心代码
void SimpleSelectionSort(int arr[] , int length) {
	int i , j , min;
	for(i = 0 ; i < length -1 ; i ++) {
		min = i;
		for(j = i+1 ; j < length ; j++)
			if(arr[j] < arr[min])
				min = j ;
		Swap(&arr[i] , &arr[min]);
	}
}
核心代码分析:
外层for循环,是比较的每个位置,因为等到前n-1个进行排序后,最后一个元素不必进行排序,所以只进行n-1次循环;
内层for循环,比较各个位置的具体比较过程,从比较位置的后一个位置开始,将最小值的位置进行存储,然后比较到数组最后一个元素,然后将最小位置的数据和比较位置进行交换。

时间复杂度

首先,共需要进行N(N-1)/2次:n+(n-1)+(n-2)+......+(n-n+1)次比较,所以时间复杂度为O(N²);

空间复杂度:

其次,没有开辟多余数组空间,所以空间复杂度为O(1);

算法稳定性:

最后,我跟大家提到过的,这个算法是不稳定的。
存在一个待排序数组:2 2 1
然后按照我们的算法,第一次比较得到最小值为1,然后将1和首位元素2进行交换,而此刻首位元素2就到了最后一个元素位置,和数组中另外一个和它相等的元素的领先关系发生变化。
算法稳定性的意义:
大家可能会疑惑,为什么要去关心稳定性?
事实上,的确从某种程度上来说,稳定与不稳定其实没什么用,但是在一些复杂的数据对象的时候就有用了。
比如:
我们去排一个成绩,要求分数从高到低同时按照姓氏笔画。
如果采用了简单选择排序,你在排好了姓氏再去排成绩的时候,就有可能被打乱了。
例子虽不是很恰当,重在理解。

稳定性的意义

	摘自:https://www.cnblogs.com/lxy-xf/p/11321536.html

如果只是简单的进行数字的排序,那么稳定性将毫无意义。
如果排序的内容仅仅是一个复杂对象的某一个数字属性,那么稳定性依旧将毫无意义
如果要排序的内容是一个复杂对象的多个数字属性,但是其原本的初始顺序毫无意义,那么稳定性依旧将毫无意义。
除非要排序的内容是一个复杂对象的多个数字属性,且其原本的初始顺序存在意义,那么我们需要在二次排序的基础上保持原有排序的意义,才需要使用到稳定性的算法,例如要排序的内容是一组原本按照价格高低排序的对象,如今需要按照销量高低排序,使用稳定性算法,可以使得想同销量的对象依旧保持着价格高低的排序展现,只有销量不同的才会重新排序。(当然,如果需求不需要保持初始的排序意义,那么使用稳定性算法依旧将毫无意义)
换句话说,以某种关键字的方式排序后,能不影响到其他关键字原来排序结果的方法就是稳定的,比如一开始按照价格高低排序结果为 a(10元,卖了5个) b(8元,卖了20个) c(6元,卖了20个) d(4元,卖了30个),则按照销量重拍后如果保持
d(30个,价格为4元) b(20个,价格为8元) c(20个,价格为6元)
a(5个,价格为10元),则说明该方法为稳定的,而如果出现c在b前,破坏了排序前b在c前的顺序,则说明这个方法是不稳定的

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!