折半、二路插入排序

折半插入排序:直接插入排序是將待插入元素與前面的元素一一比較,尋找合適的位置插入。而折半插入是通過折半來查找位置,所謂折半(可以參考二分查找)就是定義兩個變量分別指向頭start和尾end,取其中間值mid。如果待插入元素大於mid位置上的元素就這mid和end之間再查找,如果小於,則在start和mid之間查找。然後不斷縮小範圍,直到尋找到合適的位置(大於左邊小於右邊),然後就是元素的插入。

 1 #include<stdio.h> 
 2 #define n 6
 3 
 4 
 5 void binaryInsertSort(int num[]){
 6 
 7     int start,end,mid,i,j,t;
 8     for(i=1;i<n;i++){
 9         start = 0;                        //開始位置從0開始 
10         end = i-1;                        //結束位置在待插入元素的前一個位置 
11         while(start<=end){                //循環條件 
12             mid = (start+end)/2;         
13             if(num[i]>=num[mid])        //如果此條件成立 
14                 start = mid + 1;        //就說明待插入元素的插入位置應該在mid和end之間 
15             else
16                 end = mid - 1;            //否則說明待插入元素的插入位置應該在start和mid之間 
17         }
18         
19         if(start>mid)        //如果start>mid,說明待插入元素比mid位置的元素大,但比mid+1位置上的元素小 
20             mid++;            //此時插入位置應該是mid+1
21                             //還有一種情況就是end<mid,說明待插入元素比mid位置的元素小 
22                             //此時插入位置應該是mid
23                 
24         t = num[i];                //此處就是元素的插入
25         for(j=i-1;j>=mid;j--)    //使用直接插入排序代碼思想在此處插入元素         
26             num[j+1] = num[j];
27         num[j+1] = t;
28         
29     }
30     
31 }

 

二路插入排序:前面的插入排序每次插入元素的時候都會移動較多的元素,二路插入排序對其進行了改善。思路是:以第一個元素作爲比較元素,後面所有大於該元素的數全部放在前面,所有小於元素的數放在後面,大於或小於部分的元素在插入的時候使用直接插入排序來保證有序,當所有元素分配好後,其實數組已經變成兩個有序區,在組合好就完成排序了。

定義first、final指向兩個有序區,圖解如下:

 

 1 #include<stdio.h>
 2 #define n 6
 3 
 4 
 5 void twoInsertSort(int num[]){
 6     
 7     int i,j,first,final,temp[n+1]={0};    //臨時存放數組比原有數組多一個空間 
 8     first = 0;                            //first、final分別指向臨時存放數組的開頭和結尾 
 9     final = n;
10     temp[0] = num[0];                    //數組第一個元素作爲比較元素 
11     
12     for(i=1;i<n;i++){                    
13         if(num[i]>=num[0]){                //大於第一個元素的數放在臨時數組的前面 
14             j = first;                    //first作爲大於第一個元素的數的最後元素的下標 
15             while(num[i]<=temp[j]){        //在這裏使用直接插入,使其有序 
16                 temp[j+1] = temp[j];     
17                 j--;
18             }
19             temp[j+1] = num[i];
20             first++;
21         }
22         else{
23             j = final;                    //小於第一個元素的數放在臨時數組的後面 
24             while(num[i]>temp[j]){        //在這裏使用直接插入,使其有序 
25                 temp[j-1] = temp[j];    
26                 if((++j)>=n+1)            //這裏是爲了防止數組向後越界 
27                     break;
28             }
29             temp[j-1] = num[i];
30             final--;                    //final作爲小於第一個元素的數的最前元素的下標  
31         }                                //但final指向了最前元素的前一個位置    
32     }
33     
34     for(i=0;i<n-1-first;i++)            //將臨時數組存放到原來的數組 
35         num[i] = temp[++final];
36         
37     for(j=0;i<n;j++,i++)
38         num[i] = temp[j];
39     
40 }
41 
42 void main(){
43     
44     int i,num[n] = {890,761,812,761,810,261};
45     twoInsertSort(num);
46     
47     for(i=0;i<n;i++)
48         printf("%d ",num[i]);
49     
50 }

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章