1.插入排序(insertion_sort)o(n2)
對少量資料排序很有效,不需要額外的儲存空間。待排序列已經是從小到大,最壞就是逆序的時候了。且是穩定的。
#include #include int exchange(int *a, int i, int j);
int insert(int *a, int s, int e);
int main(int argc, char *argv)
; insert(a, 0, 4);
int i;
for(i=0; i<5; i++)
printf("%d\n", a[i]);
}int exchange(int *a, int i, int j)
int insert(int *a, int s, int e)
a[++j] = key;//這裡的++很重要,可以測試當正好有序時,while條件不成立,必須是自己的值賦給自己,key為a[i],所以a[++j]也必須為a[i]
}}
2.歸併排序(merge_sort) o(nlogn) 還是穩定的,這個在時間複雜度為o(nlogn)不常見
需要用到遞迴和分治(兩種方法經常結合起來使用來形成高效的演算法),推導時間複雜度用到了主定理這個牛x的定理。
#includeusing namespace std;
void merge_sort(int *a, int s, int e);
void merge(int *a, int s, int m, int e);
int main()
; merge_sort(a, 0, 9);
for(int i=0; i<10; i++)
printf("%d\n", a[i]);
return 0;
}void merge_sort(int *a, int s, int e)
; maopao(a, 0, 4);
int i;
for(i=0; i<5; i++)
printf("%d\n", a[i]);
}int maopao(int *a, int s, int e)
int exchange(int *a, int i, int j)
4.堆排序o(nlogn)
不穩定。但是時間複雜度很穩定,不管什麼情況都是nlogn,可以確切知道在什麼時間範圍內。有特殊的應用像什麼優先順序佇列,前多少大的問題。
#include #include using namespace std;
int build_max_heap(int *a, int heap_size); //這裡heap_size理解為下標的最大值加一,即為堆裡面元素的個數
int heap_sort(int *a, int len); //這裡排序的時候,陣列a的下標必須是從0開始,否則不會滿足父結點和左右孩子結點的關係
int max_heapify(int *a, int i, int heap_size); //調整使得a[i]為父節點的堆為大頂堆
int exchange(int *a, int i, int j);
int main(int argc, char *argv)
; int len = 5;
heap_sort(a, 5);
int i;
for(i=0; i<5; i++)
printf("%d\n", a[i]);
return 0;
}int exchange(int *a, int i, int j)
int max_heapify(int *a, int i, int heap_size)
return 0;
}int build_max_heap(int *a, int heap_size)
int heap_sort(int *a, int len)
}
5.快排o(nlogn)
用的最多了,雖然與堆排序時間複雜度一樣,但大多數情況下,前面的常數較小,比堆排序多數情況下速度快。
#include #include void quicksort(int *a, int s, int e);
int partition(int *a, int s, int e);
void exchange(int *a, int i, int j);
int main(int argc, char *argv)
; quicksort(a, 0, 4);
int i;
for(i=0; i<5; i++)
printf("%d\n", a[i]);
return 0;
}void exchange(int *a, int i, int j)
void quicksort(int *a, int s, int e)
}int partition(int *a, int s, int e)
element;
void bucket_sort(int *values, int s, int e);
int main()
; bucket_sort(values, 0, 19);
for(int i=0; i<20; i++)
printf("%d\t", values[i]);
printf("\n");
return 0;
}void bucket_sort(int *values, int s, int e)
else //桶內有元素
//while結束後有三種情況,一是temp為空,元素最大應插入桶末尾,二是找到比待插入元素大的值,pre不為空,元素應插入到pre後面。三是當pre為null時,插入到桶開頭
if(temp == null)
else
else}}
}//-----排序後輸入到values中-----
int j = 0;
for(int i=0; ivalue;
temp = temp->next;}}
}
穩定性總結,選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法,而氣泡排序、插入排序、歸併排序和基數排序是穩定的排序演算法。選擇演算法時不能光看時間複雜度,要結合數字的特徵。一般情況下基數排序時間複雜度為o(n),看上取要比快速排序的o(nlgn)要好,然而,在兩個時間中隱含在o記號中的常數因子是不同的,儘管基數排序執行的變數要比快排少,但是每一遍所需的時間都要長的多。哪個排序方法好取決於底層機器的實現(快排通常比基數排序更為有效的利用硬體快取),同時還取決於輸入的資料。另外利用計數排序作為中間穩定排序的基數排序不是原地排序,而很多o(nlgn)的比較排序演算法則可以做到原地排序。因此當記憶體資源容量比較寶貴的時候,像快排這樣的原地排序演算法可能是更為可取的。
基本排序演算法總結
排序演算法很多,這裡做個總結,最重要的是記住演算法思想,而不是記住程式怎麼寫。程式過一段時間就會忘了,演算法原理熟悉了現場寫出來應該是很容易的。時間複雜度為o n 2 的三種排序演算法 插入排序 選擇排序 氣泡排序。插入排序 插入排序是選定元素找位置。對於位置為p上的元素,假定0 p 1的元素已經排...
基本排序演算法總結
排序演算法的評價 評價排序演算法的一般準則是 平均情況下的排序速度 最優最劣情況下的速度 行為是否自然 是否以相等的關鍵字重排元素 陣列的排序速度直接與比較 comparison 次數和交換 exchange 次數相關,其中交換的作用更大,因為占用的時間多。如果頻繁遭遇到最優最劣情況,則最優和最劣情...
基本排序演算法總結
參考部落格 傳送門 目錄 各排序時間複雜度 氣泡排序 選擇排序 插入排序 希爾演算法 堆排序 氣泡排序 比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。在這一點,最後的元素應該會是最大的數。針對所有的元素重複以上的步驟,除了最後乙個。...