1. 程式人生 > >插入排序演算法之折半插入排序演算法

插入排序演算法之折半插入排序演算法

之前有學過二分查詢,其實折半插入跟二分查詢都是同一個原理。在百度百科開了折半排序演算法的原理後,自己試著根據原理寫出了版本一的演算法,版本二是參照巨人的實現思想,版本二才是重點。版本一可以忽略不看。

演算法同樣的目的是尋找正確的插入點。

版本一:

實現思想:

第一步:獲取折半後的下標

第二步:判斷插入值是否小於折半處的值,如果小於,而且 小於折半處前一個值 ,則往左再次折半(為什麼要小於折半處減一的值,舉個列子,原有排序 1,3,5,8  需要插入的值是4,正確的插入位置是3和5之間,第一次折半點的值為5,當4小於5,大於3時就不需要再折半了。)

第三步:當大於折半值的情況,向右再次折半。

第四步:當且僅當插入值大於折半值並且小等於於折半後一個的時候,插入點為折半點+1

重複第二第三步 直至找到插入點

//折半插入排序
public static void zbcrpx(){
int[] a={1,8,3,4,5,6,733,10};
//從開始所有遍歷
for(int i=1;i<a.length;i++){
//要插入的值
int temp=a[i];
//獲取折半點
int j=(i+1)/2;
//當小於折半點並且小於折半-1,折半點大於零的時候
while(temp<a[j]&&j>0&&temp<a[j-1]){
//向左再次折半 

j=j/2;
}
//當大於折半點並大於折半點+1時
while(temp>a[j]&&temp>a[j+1]){
//向右再次折半
j=(j+i)/2;
}
//僅當大於折半,且小於等於折半時,插入點為j
if(temp>a[j]&&temp<=a[j+1]){
j=j+1;
}
//得到了應該插入的位置之後,將陣列後移
for(int k=i;k>j;k--){
a[k]=a[k-1];
}
a[j]=temp;
}
for(int j=0;j<a.length;j++){
System.out.print(a[j]+",");
}
}

版本二:

//折半插入排序
public static void zbcrpx2(){
int[] a={1,8,3,4,5,6,733,10};
//從一開始遍歷
for(int i=1;i<a.length;i++){
//拿出要對比的資料值
int temp=a[i];
//最小對比值下標
int mins=0;
//最大對比值下標  
int maxs=i-1;
//控制迴圈條件
while(mins<maxs){
//設定折半點
int mid=(mins+maxs)/2;
//如果小於折半點,則對比左區間
if(temp<a[mid]){
maxs=mid-1;
}else{
//否則 對比 右區間
mins=mid+1;
}
}
//mins為插入點
for(int j=i;j>mins;j--){
//往後移
a[j]=a[j-1];
}
//最後將對比數置於mins處
a[mins]=temp;

}

for(int j=0;j<a.length;j++){
System.out.print(a[j]+",");
}
}