二分法排序


    二分法排序其實是一種改進的插入排序,也是通過查找待插入位置來實現排序,這和插入排序是類似的。

    算法思想,在插入第i個元素時,對前面的0~i-1元素進行折半,先跟他們中間的那個元素比,如果小,則對前半部分再進行折半,否則對后半進行折半,

直到left<right,然后再把第i個元素前1位與目標位置之間的所有元素后移,再把第i個元素放在目標位置上。

    二分法實際上沒有進行排序,只進行了有查找。所以當找到要插入的位置時,必須從移動最后一個記錄開始,向后移動一位,再移動倒數第2位,直到要插入的位置的記錄移后一位。

    下面的圖展示了二分法排序的工作原理,看圖

    下面通過代碼來實現二分法排序,上代碼

 1 #include<iostream>
 2 using namespace std;
 3 
 4 void dichotomizingsort(int a[],int n)  //升序排列
 5 {
 6    int i,j,mid=0,left,right,tem=0;
 7    for(i=1;i<n;i++)
 8    {
 9        tem=a[i];
10        left=0;  //指向有序表的低位
11        right=i-1;   //指向有序表的高位
12        while(left<=right)  //當left和right向中間靠攏的時候發生碰撞就結束排序
13        {
14           mid=(left+right)/2;  //取有序表中間的那一個元素
15           if(a[mid]>tem)   
16                     right=mid-1; //待插入元素比大中間元素小,就對前半部分再折半    
17           else
18                     left=mid+1;  //待插入元素不小於中間元素,就對后半部分再折半 
19         }
20        for(j=i-1;j>=left;j--)  //left就是在有序表中待插入的位置,但要先把left之后的所有元素向后移動一位
21        {
22             a[j+1]=a[j];
23        }
24        a[left]=tem;  //移動后就可以插入了
25        cout<<""<<i<<"次待插入的數據是:"<<tem<<endl;
26        cout<<"此時有序表中的數據位:";
27        for(j=0;j<=i;j++)
28            cout<<a[j]<<" ";
29        cout<<endl;
30    }
31 }  
32 int main()
33 {
34     int a[10]={34,4,78,35,3,64,45,18,26,35};
35     dichotomizingsort(a,10);
36     cout<<"執行插入排序后數組為:";
37     for(int i=0;i<10;i++)
38         cout<<a[i]<<" ";
39     return 0;
40 }

測試結果如下:

 

最后來說一下復雜度

空間復雜度:和插入排序一樣,只用到了一個輔助空間,為O(1)。

時間復雜度:二分法排序是一種穩定的排序算法,與二分排序的復雜度相同;最好的情況是當插入的位置剛好是二分位置 所用時間為O(log2n);最壞的情況是當插入的位置不在
二分位置, 所需比較次數為O(n),無限逼近線性查找的復雜度;而平均時間復雜度為O(n^2)。

     本人水平有限,如有錯誤歡迎指出 !謝謝!

 

      2020-04-30      18:03:11


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM