只要是接觸程式設計,接觸演算法,排序是必修的一門基礎課,它的應用之大不言而喻,下面就幾種常用排序進行實現並進行時間複雜度的分析:
1:選擇排序法
舉個例子:對於2 9 5 4 8 1 6
step1:在列表中先選擇最大元9並與最後乙個數字6交換 2 6 5 4 8 1 9;
step2:在剩餘列表選擇最大元8並與最後乙個數字1交換 2 6 5 4 1 8 9;
step3:在剩下列表選擇最大元6並與最後乙個數字1交換 2 1 5 4 6 8 9;
step4:在剩下列表選擇最大元5並與最後乙個數字4交換 2 1 4 5 6 8 9;
step5:剩下列表最大元4已經在合適位置不用交換;
step6:在剩下列表選擇最大元2並與最後乙個數字1交換 1 2 4 5 6 8 9;
最後只剩乙個數字,無需再排序,排序完成。
演算法時間複雜度分析:第一步迭代需要n-1次比較操作;第二步需要n-2個比較。。。c表示其他常見操作(賦值,每次迭代的比較)
t(n)=n-1+n-2+...+1+c*(n-1)=n^2/2-n/2+c*(n-1)=o(n^2)
**:
void sort_sele(int a,int size)
a[j+1]=re;}
}
3:氣泡排序演算法
例子:2 9 5 4 8 1 6
step1:將2 9交換,因為已經是公升序不用再動;將9 5交換成5 9;將9 4 交換成4 9;將9 8交換成8 9;將9 1交換成1 9;將9 6交換成6 9;----最大元素沉底2 5 4 8 1 6 9;
step2: 類似的將8沉底得到2 4 5 1 6 8 9;
step3:類似的將6沉底得到2 4 5 1 6 8 9;
step4:類似的將5沉底得到2 4 1 5 6 8 9;
step5:類似的將4沉底得到2 1 4 5 6 8 9;
step6:類似的將2沉底得到1 2 4 5 6 8 9;
最後完成
演算法分析:
在最好情況時第一步就發現已經有序,則無需再操作,比較此時n-1,o(n);
最壞情況:總共n-1次掃瞄;第k次掃瞄需要比較n-k次比較
t(n)=1+2+...(n-1)+c*(n-1)=o(n^2);
**:
void sort_mao(int a,int size)
}}
4:歸併排序演算法:
它是一種遞迴演算法,將陣列劃分兩半,對每一半不斷遞迴知道得到乙個元素的陣列,然後對最終子陣列進行歸併排序
演算法效能分析:t(n)=t(n/2)+t(n/2)+合併時間
第乙個t(n/2)是陣列前一半所需,第二個t(n/2)是陣列後一半所需,合併時間包括n-1次比較和n次n次移動
t(n)=t(n/2)+t(n/2)+2*n-1=2*t(n/2)+2*n-1=2*(2*t(n/4)+2*n/2-1)+2*n-1=...=2nlogn+!=o(nlogn);
**:
歸併演算法之分半部分
void copy(int source,int sindex,int dest,int dindex,int len)//將a,b裡面較小的放入temp,直到乙個放完
while(i11)
}
5:快速排序演算法:
首先在陣列中選擇乙個元素做樞軸,將陣列分為兩部分,第一部分都小於樞軸,第二部分都大於,隨後對子陣列遞迴使用快速排序
例如2 9 5 4 8 1 6
step1:選擇第乙個元素2為樞軸,分成兩部分:1 2 5 4 8 9 6
step2:對於5 4 8 9 6 選擇第乙個元素5為樞軸,分成4 5 8 9 6
step3:對於8 9 6以排好序
演算法效能:快速演算法主要分為劃分函式部分,在最壞情況下,需要花費n次比較,n次移動故劃分時間複雜度o(n)
t(n)=t(n/2)*2+n(劃分時間)=o(n*logn)
**:
//快速排序之劃分
int part(int a,int first,int last)
} //返回此次樞軸的座標
while(high>first&&pivote<=a[high])high--;
if(pivote>a[high])
else return first;}
//快速排序
void quicksort(int a,int first,int last)
}void quicksort(int a,int size)
5:堆排序演算法
二叉樹滿足:每個節點都大於等於其任何子節點:首先使用heap類建立乙個物件,使用add函式將元素入堆,然後使用remove函式刪除返回,從而完成排序
演算法效能分析:h表示乙個n個元素的堆的高度,由於堆是完全二叉樹,所以第k層有2^(k-1)個節點,第h層至少乙個節點,至多2^(h-1)
1+2.。。+2^(h-2)可以得到 h-1t(n)=o(n*logn)+o(n*logn)=o(n*logn)
**:
#include"heap.h"
void sort_sort(int a,int size){
heapheap;
for(int i=0;i
總結:一、歸併排序和快速排序都使用了分而治之思想,歸併重在列表合併操作,發生在子列表都排序之後;而快速排序重在列表劃分,發生在子列表都排序之前。歸併最壞情況好於快速,但是平均情況都是o(n*logn),但是歸併還需要乙個臨時陣列故空間複雜度高一些。堆的時間複雜度也是o(nlogn),不用額外陣列。冒泡,插入,選擇的平均複雜度o(n^2)
二、選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法,而 冒泡 排序、插入排序、歸併排序和基數排序是穩定的排序演算法。
排序演算法效率分析
目錄 排序方法 時間複雜度 平均 時間複雜度 最壞 時間複雜度 最好 空間複雜度 穩定性氣泡排序 o n2 o n2 o n o 1 穩定選擇排序 o n2 o n2 o n2 o 1 不穩定插入排序 o n2 o n2 o n o 1 穩定希爾排序 o n1.3 o n2 o n o 1 不穩定快...
幾種排序演算法及其效率對比
public class bubblesort sort arr system.out.println arrays.tostring arr long start system.currenttimemillis sort arr long end system.currenttimemillis...
內排序演算法
每次需要排序的時候總是會忘記基本的排序演算法,為了防止自己再次忘記,寫個部落格加深自己的印象 簡單選擇排序大概就是最簡單我們最容易想到的一種排序方法,一共進行n 1次選擇,在第i次選擇中選擇第i小的數放在相應的位置。我們可以想象一種場景,有一些賬單需要我們按照時間進行排序,我媽每次選擇最早的一張拿在...