我與插入排序二三事

原寫(xiě)作時(shí)間 2013-03-27

關(guān)于排序的算法有很多。作為初學(xué)者。我在掌握了冒泡排序后掌握的第二個(gè)排序算法是插入排序。一個(gè)多月前看了一些資料,了解了排序的思想,然后自己摸索出了代碼的寫(xiě)法。并一直這樣寫(xiě)了這么久。直到今天看了《算法導(dǎo)論》的時(shí)候,才恍然大悟,原來(lái)自己一直寫(xiě)的插入排序并不十分正確。雖然思想是相通的。但是運(yùn)行的效率卻相差很多。
比如一個(gè)數(shù)列。用數(shù)組表示。a[n]。
我寫(xiě)的插入排序是這樣

for(i=0;i<n;i++)  
{  
    scanf("%d",&a[i]);  
    for(j=0;j<i;j++)  
    {  
        if(a[i]<a[j])  
        {   
              t = a[i];  
             a[i] = a[j];  
             a[j] = t;  
        }  
}  

這樣寫(xiě)是一種邊初始化賦值編排序的寫(xiě)法。如果是處理一段已經(jīng)序列。則直接寫(xiě)成

for(i=1;i<n;i++)  
for(j=0;j<i;j++)  
{  
    if(a[i]<a[j])  
    {   
        t = a[i];  
        a[i] = a[j];  
        a[j] = t;  
    }  
}  

//以上兩種方法第二個(gè)for語(yǔ)句也可以改成

for(j-i-1;j>=0;j--)  
{  
    if(a[i]<a[j])  
    {  
        t = a[i];  
        a[i] = a[j];  
        a[j] = t;  
    }  
}  

看到這里你會(huì)發(fā)現(xiàn)這里也是用的插入排序的思想。只不過(guò)關(guān)鍵是在插入的處理上。我的算法比正統(tǒng)算法差了好多。大家都知道計(jì)算機(jī)的數(shù)據(jù)插入無(wú)法直接像加、減、乘、除、賦值那樣一步到位。正規(guī)的寫(xiě)法是:

for(i=1;i<n;i++)  
  
 t=a[i];  
for(j=i-1;j>0;j--)  
{  
     if(a[j]>t)  
     a[j+1]=a[j];  
 }  
 a[i+1]=t;  

假設(shè)一次賦值運(yùn)算的時(shí)間為1,然后在最壞的情況,逆序的時(shí)候,我原來(lái)的寫(xiě)法需要移動(dòng)的次數(shù)分別為1、2、3……n-1。一共是n*(n-1)/2次。每次移動(dòng)實(shí)際是三次賦值運(yùn)算,時(shí)間為3倍n*(n-1)/2。而正規(guī)的的寫(xiě)法移動(dòng)次數(shù)分別是1、2、3、……n-1每次移動(dòng)做一次賦值運(yùn)算。最后的“插入”也是一次賦值。所以時(shí)間一共是n*(n-1)/2。所以我原來(lái)的寫(xiě)法效率與之相差太多啦。

怎么樣,同樣的思想(額,其實(shí)是不完全相同),寫(xiě)出來(lái)的程序效率還是不同的。【以上內(nèi)容倉(cāng)促寫(xiě)就,或有訛誤。】
關(guān)鍵點(diǎn)在于兩者在于“插入”方法的處理上。我有這樣一種設(shè)想,就是用鏈表的方式存儲(chǔ)元素。插入的時(shí)候直接修改指針。時(shí)間效率或許會(huì)有提高。我也沒(méi)驗(yàn)證。不過(guò)即使我的設(shè)想是正確的,可以肯定的是那將是一種犧牲空間的時(shí)間優(yōu)化法。


后記 2017-09-13

現(xiàn)在看來(lái)當(dāng)時(shí)寫(xiě)的分析比較拙劣。實(shí)際時(shí)間復(fù)雜度中的常數(shù)系數(shù)的大小是基本可以忽略的。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容