雖然我之前寫過一篇部落格,關於qsort和sort函式,可以快速的進行排序,但是怎麼寫排序演算法還是要懂的。今天我對排序演算法進行一次小結,結合我本學期程式設計高階班所學和在oj上刷題經驗來敘述。
一、冒泡法排序
這個排序演算法真是爛大街了,我同學看見排序立刻就能打出這個演算法。雖然效率低下,時間複雜度為n^2,不過確實容易理解。對n個數字組成的陣列,進行(n-1)次排序,每次都比較相鄰兩個數字的大小,如果反向,則交換位置。我們可以對其進行優化,思路是:記錄下每次排序過程中最後一次排序的位置,下次只用比較到這個位置就行了,當有一次迴圈沒有進行比較時,即可結束迴圈。貼出**:
//普通氣泡排序
void mp(int a,int n)
}p=j;
j=0;
}}
二、直接插入排序
沒有技術含量的排序演算法之一,同樣n^2的時間複雜度,每次加入乙個數,選擇適合它的位置,進行n次選擇。下面貼出**:
void zjcr(int a,int n)
}}
三、希爾排序
這是一種縮小增量排序,一般情況下為n^2的時間複雜度,如果陣列基本有序,則效率可達到線性級別。其本質為把陣列分成n/2組、n/4組、n/8組、……2組、1組分別進行排序。下面貼出**:
void shell(int a,int n) //希爾排序
while(l!=mid+1) b[t++]=a[l++];
while(r!=right+1) b[t++]=a[r++];
for(l=left;l<=right;l++) a[l]=b[l];
return 0;
}void mergesort(int
left,int
right)
}/*********************/
五、快速排序
這個排序演算法也有nlogn的時間複雜度,雖然我不常用(因為它在我剛起步時難以理解),但確實**簡單,只用乙個子函式,而歸併排序得寫兩個子函式(麻煩ing)。其本質思想為:從陣列整體開始,以某個數字(陣列內已存在的)為基準,小於它的在一邊,大於它的在一邊,而後對兩邊再用快速排序,直到陣列只有乙個資料為止。下面貼上**:
/****快速排序*********/
void quicksort(int a,int left,int right)
}quicksort(a,left,l);
quicksort(a,l+1,right);
return;
}/********************/
六、堆排序
老實說,雖然我在程式設計高階班上學了這個演算法,讓我寫也能寫出來,但總有一些生疏,或者說理解不透徹,但它的演算法效率相當高,雖然時間複雜度也為nlogn,但在某種程度上甚至快於快排和歸併。本質為:建立乙個大頂堆(小頂堆),而後每次都將堆頂和堆尾交換位置,並預設堆尾的資料脫離堆,接著重新建堆重複上述過程,直到只有乙個資料為止。貼上**:
void heapdown(int a,int i,int n)
}
那麼今天這次總結就到此為止了♪(^∇^*)。 排序演算法小結
1 快速排序 quicksort 快速排序是乙個就地排序,分而治之,大規模遞迴的演算法。從本質上來說,它是歸併排序的就地版本。快速排序可以由下面四步組成。1 如果不多於1個資料,直接返回。2 一般選擇序列最左邊的值作為支點資料。3 將序列分成2部分,一部分都大於支點資料,另外一部分都小於支點資料。4...
排序演算法小結
1 歸併排序 3.區別與聯絡 遞迴是從未知推到已知,相當於把未知的東西壓入棧,等到可以算出結果了,就一步一步出棧。迭代是從已知到未知,從已知的東西一步一步推至目標。遞迴與迭代就好像一對逆元。遞迴的 更加清晰,但開銷更大,也更容易出錯,除錯較困難 而迭代的 編寫更困難,但速度和開銷較小。4.空間占用 ...
排序演算法小結
演算法過程 假設乙個無序的序列,該演算法將其分成兩部分,前一部分已經完成排序 有序,一開始時只有乙個元素 後一部分任然無序,將後面序列選擇第乙個插入到前面的有序序列,如此直到所有完全有序。複雜度 最簡單的即為,整個序列原來即有序,按照一種最 省事 的方式,我們僅需比較n 1次即可。最複雜的情況,應該...