參考資料:穩定:如果a原本在b前面,而a=b,排序之後a仍然在b的前面。經典排序演算法過程、經典排序演算法性質、《王道資料結構》、嚴蔚敏《資料結構》
不穩定:如果a原本在b的前面,而a=b,排序之後 a 可能會出現在 b 的後面。
時間複雜度:對排序資料的總的操作次數。反映當n變化時,操作次數呈現什麼規律。
空間複雜度:是指演算法在計算機內執行時所需儲存空間的度量,它也是資料規模n的函式。
// 與第i個元素交換位置
}}
void
bubblesort
(int a,
int n)
if(flag==
false
)return
;// 本次遍歷沒有發生交換,說明已經ok了}}
}
// 直接插入排序
void
insertsort
(int
* h, size_t len)
//希爾排序
void
shellsort
(int
* h, size_t len)
最終左右指標重疊:讓key左邊的都《她,右邊的都》她
然後遞迴左右兩邊。
過程:以20 40 50 10 60 為例
void
quicksort
(int a,
int left,
int right)
}int
partition
(int a,
int left,
int right)
a[left]
= key;
// 把基準元素放到它最終位置
return left;
// 返回基準元素的位置,用來劃分下面的兩個子陣列
}
時間效率:快排的執行時間和劃分是否對稱有關:
若是隨機選取起點,則**如下:
// 快速排序,隨機選取哨兵放前面
void
quicksort
(int
* h,
int left,
int right)
// 倆指標重疊後,此輪遍歷結束,找到key的最終位置
h[i]
=key;
// 繼續對兩邊的子陣列同理操作(遞迴)
quicksort
(h,left,i-1)
;quicksort
(h,j+
1,right)
;}
// 歸併排序-遞迴
void
merge
(vector<
int> a,
int low,
int mid,
int high)
// 比較b左右兩段子陣列的元素,較小的值複製到a
else
k++;}
while
(i<=mid) a[k++
]=b[i++];
// 有一邊遍歷完了,剩下的都直接放到a裡。
while
(j<=high)a[k++
]=b[j++];
}void
mergesort
(vector<
int>a,
int left,
int right)
}
非遞迴法詳見leetcode題解
// 堆排序-向下調整
void
movedown
(vector<
int>
& array,
int first,
int last)
// 將更大的子節點與根節點比較,更大的置於根節點。即:若根節點值小於子節點值,則交換
if(array[first]
< array[curindex]
)else}}
// 從最下面的部分開始,把它和子樹調整成堆的形式;
// 然後沿著陣列往前(堆往上的一層)調整成更大的堆。
void
buildheap
(vector<
int>
& array)
}// 堆排序
void
heapsort
(vector<
int>
& array)
}
時間效率:n個結點,需要d趟分配和收集,一趟分配需要o(n),一趟收集需要o( r),時間複雜度為:o(d(n+r)),與序列的初始狀態無關穩定的。
適合字串和整數這種有明顯結構特徵的關鍵碼。
排序演算法 堆排序演算法實現及分析
堆排序 heap sort 就來利用堆 假設利用大頂堆 進行排序的方法。它的基本思想是,將待排序的序列構成乙個大頂堆。此時,整個序列的最大值就是堆頂的根結點。將它移走 其實就是將其與堆陣列的末尾元素交換,此時末尾元素就是最大值 然後將剩餘的n 1個序列重新構造成乙個堆,這樣就會得到n個元素中的次小值...
排序演算法 簡單選擇排序演算法實現及分析
簡單選擇排序 selection sort 就是通過n 1次關鍵字排序之間的比較,從n i 1個記錄中選擇關鍵字最小的記錄,並和第i 1 i n 記錄交換。這是一般書上的定義。實際上選擇排序,就是每一輪選者乙個最值出來,然後在剩下的資料中又選擇乙個最值出來,直到資料被選擇完畢。這就是所謂的簡單選擇排...
排序演算法實現分析
選擇排序 快速排序 希爾排序 堆排序不是穩定的排序演算法。氣泡排序 插入排序 歸併排序和基數排序是穩定的排序演算法。冒泡法 這是最原始,也是眾所周知的最慢的演算法了。他的名字的由來因為它的工作看來象是冒泡 複雜度為o n n 當資料為正序,將不會有交換。複雜度為o 0 直接插入排序 o n2 選擇排...