What’s more important than performance?
> modularity
> correctness
> maintainability
> functionality
> robustness
> user-friendliness
> programmer time
> simplicity
> extensibility
> reliability
Why study algorithms and performance?
> Algorithms help us to understand scalability.
> Performance often draws the line between what is feasible and what is impossible.
> Algorithmic mathematics provides a language for talking about program behavior.
> The lessons of program performance generalize to other computing resources.
> Speed is fun!
插入排序法(少量資料排序較好,是一種增量排序方法):O(n2)
說明:縮排代表程式結構,三角形代表注釋,箭頭表示賦值。
Running time
• The running time depends on the input: an already sorted sequence is easier to sort.
• Parameterize the running time by the size of the input, since short sequences are easier to sort than long ones.
• Generally, we seek upper bounds on the running time, because everybody likes a Guarantee.
Kinds of analyses
Worst-case: (usually)
• T(n) = maximum time of algorithm on any input of size n.
Average-case: (sometimes)
• T(n) = expected time of algorithm over all inputs of size n.
• Need assumption of statistical distribution of inputs.
Best-case: (bogus)
• Cheat with a slow algorithm that works fast on some input
分治排序:O(nlogn)(是一種分結合并演算法或遞迴演算法)
演算法:
時間複雜度:
可以證明,其複雜度為O(nlogn)。
下面看一個例子:
有這樣一組資料,{5,4,1,22,12,32,45,21},如果對它進行合并排序的話,首先將它從中間分開,這樣,它就被分成了兩個數組{5,4,1,22} {12,32,45,21}.
對這兩個數組,也分別進行這樣的操作,逐步的劃分,直到不能再劃分為止(每個子數組只剩下一個元素),這樣,劃分的過程就結束了。
劃分的過程如所示:
接下來,我們進行合併作業,依照,劃分過程是從上到下進行的,而合并的過程是從下往上進行的,例如中,最下層{5},{4}這兩個數組,如果按升序排列,將他們合并後的數組就是{4,5}。{1},{22}這兩個子數組合并後是{1,22}。而{4,5}與{1,22},這兩個數組同屬一個分支,他們也需要進行合并,由於這兩個子數組本身就是有序的,所以合并的過程就是,每次從待合并的兩個子數組中選取一個最小的元素,然後把這個元素放到合并後的數組中,前面兩個數組合并後就是{1,4,5,22}。依次類推,直到合并到最上層結束,這是資料的排序已經完成了。
合并的過程如所示。這個過程是從下往上的。
C語言實現代碼如下:
1#include <stdlib.h> 2 3//合并過程 4void merge(int data[],int start,int mid,int end){ 5 6 7 int *tmpLeft,*tmpRight; 8 int leftSize,rightSize; 9 int l,r,j;1011 printArray(data,8);12 printf("\n");13 l = 0;14 r = 0;15 j = 0;16 leftSize = mid - start + 1;17 rightSize = end - mid;1819 tmpLeft = (int *)malloc(leftSize * sizeof(int));20 tmpRight = (int *)malloc(rightSize * sizeof(int));2122 while(j < leftSize){23 tmpLeft[j] = data[start + j];24 j++;25 }2627 j = 0;2829 while(j < rightSize){30 tmpRight[j] = data[mid + 1 + j];31 j++;32 }3334 j = 0;3536 while(l < leftSize && r < rightSize){37 if(tmpLeft[l] < tmpRight[r]){3839 data[start + j++] = tmpLeft[l++];4041 }else{4243 data[start + j++] = tmpRight[r++];44 }45 }4647 while(l < leftSize){48 data[start + j++] = tmpLeft[l++];49 }5051 while(r < rightSize){52 data[start + j++] = tmpRight[r++];53 }5455 free(tmpLeft);56 free(tmpRight);57}585960void merge_sort(int data[],int start,int end){6162 int mid;63 if(start < end){64 //將數組劃分65 mid = (start + end) / 2;66 merge_sort(data,start,mid);67 merge_sort(data,mid + 1,end);68 //合并劃分後的兩個數組69 merge(data,start,mid,end);70 }7172}