数据结构是每一个程序员必须学而且必须掌握的知识,今天开始我和大家一起学期排序这个专题首先介绍一下简单的排序---选择排序
选择排序的基本思路是
首先找到数组中最小的那个元素,其次,将它和数组的第一个元素交换位置(如果第一个元素就是最小元素那么它就和自己交换)。再次,在剩下的元素中找到最小的元素,将它与数组的第二个元素交换位置。如此往复,直到将整个数组排序。这种方法叫做选择排序,因为它在不断地选择剩余元素之中的最小者。
其代码实现为
<span style="font-size:18px;">import java.util.Comparator;
/**
* 本例子充分利用Java的知识
* 所要比较的数据类型不管是自定义的还是java内置的
* 都必须实现Comparable接口并且实现compareTo()方法
* 本例子参考Sedgewick的Algorithms(Fourth Edition)
* @author LiChunting
*
*/
public class SelectionDIY {
//将构造方法设为私有
private SelectionDIY() { }
/**
* 对传入的数据通过选择排序的方法进行比较
* 排序方式为自然排序
* 本例中采用这种排序方法
* @param a
*/
@SuppressWarnings("rawtypes")
public static void sort(Comparable[] a) {
int N = a.length;
for (int i = 0; i < N; i++) {
int min = i;
for (int j = i+1; j < N; j++) {
if (less(a[j], a[min])) min = j;
}
exch(a, i, min);
assert isSorted(a, 0, i);
}
assert isSorted(a);
}
/**
* 这个方法也是实现选择排序,不过这个方法的排序方式是通过自定义的排序方式
* @param a 要排序的数组
* @param c 自定义比较器
*/
@SuppressWarnings("rawtypes")
public static void sort(Object[] a, Comparator c) {
int N = a.length;
for (int i = 0; i < N; i++) {
int min = i;
for (int j = i+1; j < N; j++) {
if (less(c, a[j], a[min])) min = j;
}
exch(a, i, min);
assert isSorted(a, c, 0, i);
}
assert isSorted(a, c);
}
/**
* 以下各个方法是用来辅助实现排序的
*/
/**
* 比较v是否小于w,利用compareTo()方法
* 如果大于则返回真小于则是返回假
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private static boolean less(Comparable v, Comparable w) {
return v.compareTo(w) < 0;
}
/**
* 比较v是否小于w,利用compareTo()方法
* 如果大于则返回真小于则是返回假
* 但是比较方式是自己定义的
* @return
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
private static boolean less(Comparator c, Object v, Object w) {
return c.compare(v, w) < 0;
}
/**
* 交换数组中的两个值
* @param a 传入的数组
* @param i 第一个要交换的值得下标
* @param j 第二个要交换的值的下标
*/
private static void exch(Object[] a, int i, int j) {
Object swap = a[i];
a[i] = a[j];
a[j] = swap;
}
// 判断数组是否是有序使用默认的自然排序
@SuppressWarnings("rawtypes")
private static boolean isSorted(Comparable[] a) {
return isSorted(a, 0, a.length - 1);
}
//判断数组从低到高是否是有序的使用默认的排序
@SuppressWarnings("rawtypes")
private static boolean isSorted(Comparable[] a, int lo, int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(a[i], a[i-1])) return false;
return true;
}
// 判断数组是否是有序使用自定义排序
@SuppressWarnings("rawtypes")
private static boolean isSorted(Object[] a, Comparator c) {
return isSorted(a, c, 0, a.length - 1);
}
//判断数组从低到高是否是有序的使用自定义排序
@SuppressWarnings("rawtypes")
private static boolean isSorted(Object[] a, Comparator c, int lo, int hi) {
for (int i = lo + 1; i <= hi; i++)
if (less(c, a[i], a[i-1])) return false;
return true;
}
//将排序号的数组输出
@SuppressWarnings("rawtypes")
private static void show(Comparable[] a) {
for (int i = 0; i < a.length; i++) {
System.out.print(a[i]+" ");
}
}
/**
* 执行main方法测试选择排序
* @param args
*/
public static void main(String[] args) {
String[] a={"A","C","F","D","E","O"};
Selection.sort(a);
show(a);
}
}
</span>
从代码中可以看出,对于长度为N的数组,选择排序需要大约N2/2次比较和N次交换选择排序的特点是
1.运行时间和输入无关:一个已经有序的数组或是主键全部相等的数组和一个元素随机排列的数组所用的排序时间是一样的
2.数据移动是最少的:每次交换都会改变两个数组元素的值,因此选择排序用了N次交换---交换次数和数组的大小是线性关系
选择排序是比较简单的一种排序,希望大家在学习的时候能够自己写,实现其主要功能就好。
谢谢大家的阅读!