1. 冒泡排序
public interface Sort<T extends Comparable<T>> {
public void sort(T[] array);
}/**
*
* 类名: MPSort.java
* 类描述: 冒泡排序
* 备注:
* <li>比较相邻的元素。如果第一个比第二个大,就交换他们两个。</li>
* <li>对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。</li>
* <li>针对所有的元素重复以上的步骤,除了最后一个。</li>
* <li>持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。</li>
*/
public class MPSort<T extends Comparable<T>> implements Sort<T>{
@Override
public void sort(T[] array) {
if(null != array && array.length > 0){
for(int i=0; i<array.length-1; i++){
for(int j=i+1; j<array.length; j++){
if(array[i].compareTo(array[j])>0){
T temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
}
}
}2. 选择排序
/**
*
* <pre>
* 类名: XZSort.java
* 类描述: 选择排序
* 备注: 选择排序,先将第一个数和后续的数依次比较,找到最大的(或最小的)数,然后把该数和第一个数位置交换,然后依次对后续的数循环做此处理。
* </pre>
*/
public class XZSort<T extends Comparable<T>> implements Sort<T>{
@Override
public void sort(T[] array) {
if(null != array && array.length > 0){
for(int i=0; i<array.length-1; i++){
int index = i;
for(int j=i+1; j<array.length; j++){
if(array[index].compareTo(array[j]) > 0){
index = j;
}
}
if(index != i){
T temp = array[i];
array[i] = array[index];
array[index] = temp;
}
}
}
}
}3. 插入排序
/**
*
* <pre>
* 类名: CRSort.java
* 类描述: 插入排序
* 备注:插入排序把要排序的数组分成两部分,第一部分包含这个数组的所有元素,最后一个元素除外,而第二部分只包含这一元素;
* 在第一部分排序后,再把这个最后元素插入到此刻已经排好序的第一部分的正确位置。
* </pre>
*/
public class CRSort<T extends Comparable<T>> implements Sort<T> {
@Override
public void sort(T[] array) {
if(null != array && array.length > 0){
for(int i = 1; i< array.length; i++){
for(int j = i; j > 0; j--){
if(array[j].compareTo(array[j-1]) < 0){
T temp = array[j-1];
array[j-1] = array[j];
array[j] = temp;
}
}
}
}
}
}4. 快速排序
/**
* <pre>
* 类名: KSSort.java
* 类描述: 快速排序
* 备注:
* <li>从数列中挑出一个元素,称为“基准”</li>
* <li>重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分割之后, 该基准是它的最后位置。这个称为分割(partition)操作。</li>
* <li>递归地把小于基准值元素的子数列和大于基准值元素的子数列排序。</li>
* </pre>
*/
public class KSSort<T extends Comparable<T>> {
public void sort(T[] array, int start, int end) {
int i=start;
int j=end;
T temp;
T p = array[start];
do{
while(array[i].compareTo(p)<0 && i<end){
i++;
}
while(array[j].compareTo(p)>0 && j>start){
j--;
}
if(i<=j){
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
}while(i<=j);
if(start<j){
sort(array, start, j);
}
if(i<end){
sort(array, i, end);
}
}
}
5. 归并排序(转自:http://blog.csdn.net/apei830/article/details/6591632)
/**
* 项目名: sort
* 类名: GBSort.java
* 类描述: 归并排序
* 备注: 归并排序是把已经排好序的两个序列合并成一个有序序列
*/
public class GBSort{
public static void mergeSort(Integer[] data) {
sort(data, 0, data.length - 1);
}
public static void sort(Integer[] data, int left, int right) {
if (left >= right)
return;
// 找出中间索引
int center = (left + right) / 2;
// 对左边数组进行递归
sort(data, left, center);
// 对右边数组进行递归
sort(data, center + 1, right);
// 合并
merge(data, left, center, right);
}
/**
* 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序
*
* @param data
* 数组对象
* @param left
* 左数组的第一个元素的索引
* @param center
* 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引
* @param right
* 右数组最后一个元素的索引
*/
public static void merge(Integer[] data, int left, int center, int right) {
// 临时数组
int[] tmpArr = new int[data.length];
// 右数组第一个元素索引
int mid = center + 1;
// third 记录临时数组的索引
int third = left;
// 缓存左数组第一个元素的索引
int tmp = left;
while (left <= center && mid <= right) {
// 从两个数组中取出最小的放入临时数组
if (data[left] <= data[mid]) {
tmpArr[third++] = data[left++];
} else {
tmpArr[third++] = data[mid++];
}
}
// 剩余部分依次放入临时数组(实际上两个while只会执行其中一个)
while (mid <= right) {
tmpArr[third++] = data[mid++];
}
while (left <= center) {
tmpArr[third++] = data[left++];
}
// 将临时数组中的内容拷贝回原数组中
// (原left-right范围的内容被复制回原数组)
while (tmp <= right) {
data[tmp] = tmpArr[tmp++];
}
}
}这几种排序的效率比较:
public class Test {
static Random random = new Random(System.nanoTime());
public static Integer[] getIngegerArray(int count){
Integer[] array = new Integer[count];
for(int i=0; i<count; i++){
array[i] = random.nextInt(count)+1;
}
return array;
}
public static void main(String[] args) {
int count = 100000;
Integer[] array = getIngegerArray(count);
Integer[] array1 = new Integer[count];
System.arraycopy(array, 0, array1, 0, count);
Integer[] array2 = new Integer[count];
System.arraycopy(array, 0, array2, 0, count);
Integer[] array3 = new Integer[count];
System.arraycopy(array, 0, array3, 0, count);
Integer[] array4 = new Integer[count];
System.arraycopy(array, 0, array4, 0, count);
KSSort ksSort = new KSSort();
long time1 = System.nanoTime();
ksSort.sort(array1, 0, count-1);
long time2 = System.nanoTime();
System.out.println("快速排序:排"+count+"个整数耗时:"+(time2-time1)/1000000+"ms");
Sort crSort = new CRSort<>();
time1 = System.nanoTime();
crSort.sort(array2);
time2 = System.nanoTime();
System.out.println("插入排序:排"+count+"个整数耗时:"+(time2-time1)/1000000+"ms");
Sort mpSort = new MPSort<>();
time1 = System.nanoTime();
mpSort.sort(array3);
time2 = System.nanoTime();
System.out.println("冒泡排序:排"+count+"个整数耗时:"+(time2-time1)/1000000+"ms");
Sort xzSort = new XZSort<>();
time1 = System.nanoTime();
xzSort.sort(array);
time2 = System.nanoTime();
System.out.println("选择排序:排"+count+"个整数耗时:"+(time2-time1)/1000000+"ms");<span style="white-space:pre"> </span>GBSort gbSort = new GBSort();
<span style="white-space:pre"> </span>time1 = System.nanoTime();
<span style="white-space:pre"> </span>gbSort.mergeSort(array6);
<span style="white-space:pre"> </span>time2 = System.nanoTime();
<span style="white-space:pre"> </span>System.out.println("归并排序:排"+count+"个整数耗时:"+(time2-time1)/1000000+"ms");
}
}
快速排序:排10000个整数耗时:3ms 插入排序:排10000个整数耗时:681ms 冒泡排序:排10000个整数耗时:747ms 选择排序:排10000个整数耗时:486ms
测试结果2:
快速排序:排1000个整数耗时:2ms 插入排序:排1000个整数耗时:7ms 冒泡排序:排1000个整数耗时:7ms 选择排序:排1000个整数耗时:5ms
测试结果3:
快速排序:排50000个整数耗时:20ms 插入排序:排50000个整数耗时:19009ms 冒泡排序:排50000个整数耗时:27390ms 选择排序:排50000个整数耗时:15217ms
测试结果4:
快速排序:排10000个整数耗时:3ms 插入排序:排10000个整数耗时:590ms 冒泡排序:排10000个整数耗时:665ms 选择排序:排10000个整数耗时:400ms 数组自带Api排序:排10000个整数耗时:5ms 归并排序:排10000个整数耗时:265ms
另外,再加上一个数组自带的排序方法:
time1 = System.nanoTime();
Arrays.sort(array5);
time2 = System.nanoTime();
System.out.println("数组自带Api排序:排"+count+"个整数耗时:"+(time2-time1)/1000000+"ms");输出结果:
数组自带Api排序:排50000个整数耗时:21ms