插入排序-(直接插入、折半插入、Shell排序)

import java.util.Arrays;
/**
 * 插入排序:直接插入排序、shell排序、折半插入排序
 * @author mk
 *
 */
public class InsertInSort
{
/*
*  直接插入排序:
*  第1趟將第2個元素開始,插入前面有序的序列,此時前面只有一個元素,當然是有序的
*  第2趟將第3個元素插入到前面有序的序列
*  第n-1趟將第n個元素插入到前面n-1個元素的有序序列
*  直接排序時間效率不高,最壞的情況下所有元素比較的總和爲0+1+2+...n-1=o(n2).空間效率高
*  只需要緩存一個元素O(1).
*/
public static void sortDirectInsert(DataWrap [] datas)
{
for(int i=1; i<datas.length-1; i++)
{
DataWrap tmp = datas[i];// 保存待插入序列的值
// i索引處值比前面有序的序列值小,需要插入
if(datas[i].compareTo(datas[i-1]) < 0)
{
int j = i -1;
// 整體後移一位
for(; j>=0 && datas[j].compareTo(tmp)>0; j--) datas[j+1] = datas[j];
datas[j+1] = tmp;// 將tmp插入到合適的位置
}
System.out.println("第"+i+"趟排序:"+Arrays.toString(datas));                     
}
}

/*
* 折半插入,有名二分查找,效率更快找到插入位置
*/
public static void sortBinaryInsert(DataWrap [] datas)
{
for(int i=0; i<datas.length; i++)
{
DataWrap tmp = datas[i];
int low=0, high = i-1;
while(low <= high)
{
int mid = (low + high )/2;
// 如果tmp大於low~high中間值
if(tmp.compareTo(datas[mid]) > 0)
low = mid + 1;// 限制在索引大於中間元素的那一半查找
else
high = mid - 1;// 限制小於中間元素的那一半查找
}
// 將low到i的所有元素向後移動一位
for(int j = i; j > low; j--) datas[j] = datas[j-1];
datas[low] = tmp;
System.out.println("第"+i+"趟排序:"+Arrays.toString(datas));      
}
}

/*
* shell排序是Donald L.Shell 1959年發現並以他名字命名的
*/
public static void sortShell(DataWrap [] datas)
{
int arrayLength = datas.length;
int h = 1; //h變量保存可變增量
while(h <= arrayLength / 3)h = h * 3 + 1;//按h * 3 + 1得到增量序列的最大值
while(h > 0)
{
System.out.println("===h的值:" + h + "===");
for (int i = h ; i < arrayLength ; i++ )
{
DataWrap tmp = datas[i];//當整體後移時,保證data[i]的值不會丟失
//i索引處的值已經比前面所有值都大,表明已經有序,無需插入(i-1索引之前的數據已經有序的,i-1索引處元素的值就是最大值)
if (datas[i].compareTo(datas[i - h]) < 0)
{
int j = i - h;
//整體後移h格
for ( ; j >= 0 && datas[j].compareTo(tmp) > 0 ; j-=h) datas[j + h] = datas[j];
datas[j + h] = tmp;//最後將tmp的值插入合適位置
}
System.out.println("第"+i+"趟排序:"+Arrays.toString(datas)); 
}
h = (h - 1) / 3;
}
}
public static void main(String[] args)
{
DataWrap[] dws = { new DataWrap(10, ""), new DataWrap(5, ""),
new DataWrap(8, ""), new DataWrap(3, ""),new DataWrap(14, "") };
System.out.println("排序前:" + Arrays.toString(dws));
// sortDirectInsert(dws);
// sortBinaryInsert(dws);
sortShell(dws);
System.out.println("排序後:" + Arrays.toString(dws));
/*
* 測試結果
* 排序前:[10, 5, 8, 3, 14]
* 第1趟排序:[5, 10, 8, 3, 14]
* 第2趟排序:[5, 8, 10, 3, 14]
* 第3趟排序:[3, 5, 8, 10, 14]
* 排序後:[3, 5, 8, 10, 14]
*/
/* Shell 排序測試結果
* 排序前:[10, 5, 8, 3, 14]
* ===h的值:4===
* [10, 5, 8, 3, 14]
* ===h的值:1===
* 第1趟排序:[5, 10, 8, 3, 14]
* 第2趟排序:[5, 8, 10, 3, 14]
* 第3趟排序:[3, 5, 8, 10, 14]
* 第4趟排序:[3, 5, 8, 10, 14]
* 排序後:[3, 5, 8, 10, 14]
*/
}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章