排序的方法有很多,一般言,很难说哪一种方法是最好的。每一种方法都有优缺点,有各自应用的环境。排序一般会进行两种操作1、比较两关键字大小;2、将记录从一个位置移到另一个位置;前者通常来说是必要的,而后者则可以通过改变记录存储方式来避免。后面还会用一篇专门的文章来讨论一下怎么来分析这些算法的复杂度。还请您留意,应该这就是最近一周出来!(2015.6.20前)
常见的内部排序算法大致可以分为以下六类共十种:
选择排序:(1)直接选择排序;(2)堆排序;
交换排序:(3)冒泡排序;(4)快速排序;
插入排序: (5)直接插入 排序; (6)折半插入排序;(7)Shell排序;
(8)归并排序;
(9)筒式排序;
(10)基数排序;
下面就将用十篇文章分别归纳这十种排序,这一篇是折半插入排序:
刚刚有看到有的书上还考虑的排序的稳定性,简单说就是,相同的元素在排序前后的位置有没有发生相对改变。举个例子:排序前[5*, 6, 5, 3, 1]排序后变成了[1, 3 , 5, 5*, 6],这就是不稳定排序。我们也参考这种方法,加入稳定性分析(考虑加入数据包装类)。言归正传,来说说折半插入排序:折半插入排序是对直接插入排序的改进,因为比如要插入到前半部分,而从i-1处开始搜索,效率显然很低。折半的意思是,对于从0 -- i-1处的元素,直接从(0+(i-1))/2比较,然后调整相应的搜索区间。这样能将搜索区间逐步缩小到1/2, 1/4,1/8等等,进而能快速确定插入的位置。下面是源代码:
package mymork.c20150614;
//a example to BinaryInsertSort
//blog.youkuaiyun.com/code_7
//HanChun at XiDian University
//input:7 2 0 8 4 2*
import java.util.Arrays;
//定义了一个数据包装类,用来在体现排序算法稳定性的时候更容易理解!
class DataWrap implements Comparable<DataWrap> {
int data;
String flag;
public DataWrap(int data, String flag){
this.data = data;
this.flag = flag;
}
public String toString(){
return data + flag;
}
public int compareTo(DataWrap dw){
return this.data > dw.data ? 1 : (this.data == dw.data ? 0 : -1);
}
}
public class BinaryInsertSort {
public static DataWrap[] binaryInsertSort(DataWrap[] data){
for(int i = 1; i < data.length; i++){
int low = 0;
int high = i - 1;
DataWrap tem = data[i];
while(low <= high){
int mid = (low + high) / 2;
if(tem.compareTo(data[mid]) > 0){
low = mid + 1;
}else{
high = mid - 1;
}
}
//把data[low]后的元素往后移一位,方便后面的元素插入
for(int j = i; j > low; j-- ){
data[j] = data[j-1];
}
//插入data[low]到合适的位置
data[low] = tem;
}
return data;
}
public static void main(String[] args) {
DataWrap[] data ={new DataWrap(7,""),new DataWrap(2,""),new DataWrap(0,""),
new DataWrap(8,""),new DataWrap(4,""),new DataWrap(2,"*")};
System.out.println("排序之前的元素为:" + Arrays.toString(data));
System.out.println("排序之后的元素为: " + Arrays.toString(binaryInsertSort(data)));
}
}
排序结果:
排序之前的元素为:[7, 2, 0, 8, 4, 2*]
排序之后的元素为: [0, 2*, 2, 4, 7, 8]
呵呵,你看懂了吗?欢迎拍砖,寻求跟好的排序算法。