目录
一、排序的解释
1、排序
排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。平时的上下文中,如果提到排序,通常指的是排升序(非降序)。通常意义上的排序,都是指的原地排序(in place sort)。
2、排序的稳定性
待排序的序列中,存在值相同的元素,经过排序后,值相等的先后顺序没有发生变化的排序算法称之为稳定的算法 。 就是下图中的5a和5b的先后顺序并没有发生变化。
3、 内部排序和外部排序
(1)内部排序
待排序的数据都放在内存中
(2)外部排序
数据存储在硬盘中,每次排序都需要从硬盘读取一部分内容到内存中,把这部分数据排序之后再写会硬盘。比如说桶排序,基数排序,奇数排序,这些方法都需要在特殊的场景下才可以使用,局限性比较大。
二、各大排序的测试方法
package Seven_sorts;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.ThreadLocalRandom;
/**
* 测试七大排序
*/
public class SortTest {
//生成随机数的一个类
private static final ThreadLocalRandom random=ThreadLocalRandom.current();
/**
* 产生一个大小为n的随机整数数组,数组的取值范围为[l...r]
* @param n 数组的元素个数
* @param l 数组的取值最小值
* @param r 数组的取值最大值
* @return
*/
public static int[] generaRabdomArrary(int n,int l,int r){
int[] data=new int[n];
for (int i = 0; i <n ; i++) {
//生成了一个[l...r)的随机数放在数组中
data[i]= random.nextInt(l,r);
}
return data;
}
/**
* 生成一个大小为n的近乎有序的数组
* @param n 元素个数
* @param swaptinmes 交换的次数,次数越大,数组越无序
* @return
*/
public static int[] generateSortArrary(int n,int swaptinmes){
//先生成一个有序数组
int[] data =new int[n];
for (int i = 0; i < n; i++) {
data[i]=i;
}
//对有序数组的部分元素进行交换
for (int i = 0; i <swaptinmes; i++) {
int a= random.nextInt(n);
int b= random.nextInt(n);
int temp=data[a];
data[a]=data[b];
data[b]=temp;
}
return data;
}
/**
* 深拷贝数组
* @param arr
* @return
*/
public static int[] arraryCopy(int[] arr){
return Arrays.copyOf(arr,arr.length);
}
/**
* 在指定的数组arr上测试名称为sortName的排序耗时
* @param arr
* @param sortName
*/
public static void testSort(int[] arr,String sortName){
Class<SevenSort> cla=SevenSort.class;
try {
//根据战法名称拿到算法
Method method= cla.getDeclaredMethod(sortName,int[].class);
//计时
long start=System.nanoTime();
method.invoke(null,arr);
long end=System.nanoTime();
if (isSorted(arr)){
System.out.println(sortName+"排序完成,共耗时:"+(end-start)/1000000.0+"ms");
}
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 检查当前数组是否是一个非降序数组
* @param arr
* @return
*/
private static boolean isSorted(int[] arr){
for (int i = 0; i < arr.length-1; i++) {
if (arr[i]>arr[i+1]){
System.out.println("排序算法有误!");
return false;
}
}
return true;
}
}
三、选择排序
1、直接选择排序
每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前),直到全部待排序的数据元素排完 。
9,2,5a,7,5b,4,3,6
对于这一组数据来说,最开始排序时,
待排序数组(无序区间)为[i...n),已排序数组(有序区间)为[]
当进行了第一次排序后,2,9,5a,7,5b,4,3,6
待排序数组(无序区间)为[i...n)-1,已排序数组(有序区间)为[]+1
/**
* 直接选择排序
* @param arr
*/
public static void selsctionSort(int[] arr){
//最开始的无序区间[i...n),有序区间为[]
for (int i = 0; i < arr.length; i++) {
//最小元素索引下标
int min=i;
for (int j = i+1; j < arr.length; j++) {
if (arr[j]<arr[min]){
min=j;
}
}
//此时min就是最小值的索引,进行交换操作
swap(arr,i,min);
}
}