问题?选择排序算法(Java),特点,时间复杂度,空间复杂度,优缺点
一、基本概念
选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小(大)元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小(大)元素,然后放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。
通俗的来说,就是无论是从大到小排序还是从小到大,都可以,每一次找到了最小(最大)的数,存放到序列最前端,再往后找,再找到最小(最大)放到前端序列的下一个,依次类推,直到排序完成。
二、特点
1.时间复杂度
选择排序的交换操作介于 0 和 (n - 1) 次之间。选择排序的比较操作为 n (n - 1) / 2 次之间。选择排序的赋值操作介于 0 和 3 (n - 1) 次之间。
比较次数O(n^2),比较次数与关键字的初始状态无关,总的比较次数N=(n-1)+(n-2)+...+1=n*(n-1)/2。交换次数O(n),最好情况是,已经有序,交换0次;最坏情况交换n-1次,逆序交换n/2次。交换次数比冒泡排序少多了,由于交换所需CPU时间比比较所需的CPU时间多,n值较小时,选择排序比冒泡排序快。
平均时间复杂度:
O(n2)
最坏时间复杂度:O(n2)
2.空间复杂度
O(1)
3.稳定性
如果一个元素比当前元素小,而该小的元素又出现在一个和当前元素相等的元素后面,那么交换后稳定性就被破坏了,举个例子,序列5 8 5 2 9,我们知道第一遍选择第1个元素5会和2交换,那么原序列中两个5的相对前后顺序就被破坏了,所以选择排序是一个不稳定的排序算法。
4.优点:数据移动少,速度快,空间复杂度小
5.缺点:不稳定,玄子序列容易被破坏
三、实现
工具类:
package com.itcast.util;
public class SortUtil {
public static void SystmSort(int data[]){
System.out.print("\n{");
for(int i=0;i<data.length;i++){
System.out.print(data[i]);
if(i!=data.length-1){
System.out.print(",");
}
}
System.out.print("}");
}
}
选择排序:
package com.itcast.SelectSort;
import com.itcast.util.SortUtil;
public class SelectSort {
//第一种
public static void selectSort1(int data[]){
for(int i=0;i<data.length-1;i++){
for(int j=i+1;j<data.length;j++){
if(data[j]<data[i]){
int temp = data[j];
data[j]=data[i];
data[i]=temp;
}
}
}
}
//第二种,效率稍微高一点儿
public static void selectSort2(int data[]){
if(data.length==0||data==null){
return;
}
for(int i=0;i<data.length-1;i++){
int min=i;//把当前最小值的下标定义为i
for(int j=i+1;j<data.length;j++){
if(data[j]<data[min]){
min=j;
}
}
if(i!=min){
int temp = data[i];
data[i]=data[min];
data[min]=temp;
}
}
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
int data[] = {2,3,1,5,6};
SortUtil.SystmSort(data);
// selectSort1(data);
selectSort2(data);
SortUtil.SystmSort(data);
long endTime = System.currentTimeMillis();
System.out.println("\n"+(endTime-startTime)+"MS");
}
}