演算法學習之簡單排序
簡單排序
簡單排序有三種, 氣泡排序,選擇排序,插入排序
氣泡排序
氣泡排序是一種易於實現的排序演算法, 以升序為例:
有n個數, 需要比較n-1輪, 每輪比較陣列中相鄰的兩個數, 前者大就交換兩數.
第一輪時, 最大的數就會如冒泡般移向隊尾, 下一輪比較就可以少比較一個數.
//氣泡排序
void bubbleSort(int arr[], int n){
for (int i = 0; i < n-1 ; i++ ) {
for (int j = 1; j < n - i; j++) {
if (arr[j - 1] > arr[j]) {
swap(&arr[j-1], &arr[j]);
}
}
}
}
因為用的是C語言, 遇到了java中完全遇不到的兩個bug.
第一點是交換值, 必須要傳地址才有卵用, 否則毫無卵用
// 交換函式, 必須傳遞引用才能交換成功
// 傳值只是將實參複製給了形參一份, 在函式內如何改變形參與實參無關
// 傳遞引用, &arr[i], 取地址, a = &arr[i], *a = *(&arr[i]) = arr[i]
// 因此改變的就是實參的值
void swap(int *a, int *b){
int temp = *a;
*a = *b;
*b = temp;
}
另一點是獲取陣列長度.
按照道理, 用運算子sizeof可以計算出陣列的容量(位元組數),在除以單個元素的容量就能得到陣列的長度了.
(sizeof(array) / sizeof(array[0]));
結果我真的是naive. 當我想列印陣列時, 搞了個函式
void printfArray(int arr[]){
int len = sizeof(arr) / sizeof(arr[0]);
for (int i = 0; i < len; i++) {
printf("%d, ", arr[i]);
}
}
怎麼打都只能打出兩個數字, 百思不得其解啊尼瑪
在C/C++中, 陣列在作為引數傳遞時, 會退化為同型別的指標, 並沒有辦法知道指標所指的記憶體容量,除非在申請記憶體時記住它。
無論陣列長度為多少, 以int陣列為例, sizeof(a)始終等於sizeof(int *), 所以函式中傳遞只能把傳陣列個數傳過去
void printfArray(int arr[], int len){
for (int i = 0; i < len; i++) {
printf("%d, ", arr[i]);
}
}
選擇排序
選擇排序, 以升序為例:
第一輪比較, 從arr[0]開始依次比較, 找出最小的數的下標, 記錄下來, 將arr[0]與最小值交換.
第二輪從arr[1]開始依次比較, 找出最小的數的下標, 記錄下來, 將arr[1]與最小值交換.
...
直到交換完成
void selectSort(int arr[], int n){
for (int i = 0; i < n; i++) {
int min = i;
for (int j = i + 1; j < n; j++) {
if (arr[j] < arr[min]) {
min = j;
}
}
swap(&arr[i], &arr[min]);
}
}
插入排序
插入排序的思路是,將單個數字插入有序集合. 大致思想是, 先將第一個數看做有序區, 後面的數依次插入, 形成新的有序區, 直到排序完成.
以升序為例, 比如這樣一個陣列 {4, 2, 7, 3}
第一輪, 第一個數字4看做有序區, 後面的數字插入. 開始比較2和4,發現2更小,繼續向前查詢,沒有數字,因此將2插入4的位置,4向後移。這時陣列變成了{2, 4, 7, 3}
第二次,遍歷到7,向前比較, 有序
第三次,3和7比較,7更大,3應該插入前面。繼續向前比較,比較到2才找到了合適的位置。將3插入4的位置,4、7向後移動一位。
下面開始擼程式碼
// 直接插入排序
void insertSort(int arr[], int n){
for (int i = 0; i < n; i++) {
// 後面的數比前面的數大時, 準備插入
if (arr[i] > arr[i+1]) {
// 儲存待插入的數
int temp = arr[i+1];
int j;
// 向前查詢合適的插入位置
for (j = i; j>=0 && temp < arr[j]; j--) {
// 逐步後移陣列
arr[j+1] = arr[j];
}
// 交換
arr[j+1] = temp;
}
}
}
相關文章
- 簡單排序演算法排序演算法
- 演算法學習之選擇排序和堆排序:演算法排序
- 排序演算法——簡單選擇排序排序演算法
- 演算法導論學習之五:快速排序演算法排序
- 演算法導論學習之六:歸併排序演算法排序
- 學習排序演算法(二):Pairwise方法之RankNet排序演算法AI
- Java常見排序演算法之插入排序-簡單的效能優化技巧Java排序演算法優化
- 看動畫學演算法之:排序-count排序動畫演算法排序
- 看動畫學演算法之:排序-快速排序動畫演算法排序
- 簡單的幾個排序演算法排序演算法
- 演算法學習之直接插入排序(java)演算法排序Java
- 資料結構學習筆記-簡單選擇排序資料結構筆記排序
- 演算法學習---歸併演算法簡單記錄演算法
- 看動畫學演算法之:排序-基數排序動畫演算法排序
- 演算法學習 – 歸併排序演算法排序
- 演算法學習 - 歸併排序演算法排序
- 演算法學習之路|快速排序演算法排序
- 演算法學習-遞迴排序演算法遞迴排序
- IOS中學習排序演算法iOS排序演算法
- Python學習6之簡單實戰Python
- Electron學習(三)之簡單互動操作
- 演算法學習 - 基礎排序演算法演算法排序
- 簡單排序排序
- 簡單演算法――Cisco某個學習資料演算法
- 學習筆記--- 比較排序之堆排序筆記排序
- PHP常見排序演算法學習PHP排序演算法
- 簡單學習jsJS
- Git簡單學習Git
- gin簡單學習
- SpringMVC學習筆記之---簡單入門SpringMVC筆記
- React Native學習之 ListView 的簡單使用React NativeView
- RabbitMQ學習之(四)_PHP操作RabbitMQ簡單DemoMQPHP
- SG學習筆記之RMAN簡單歸納筆記
- 【一起學習排序演算法】3 選擇排序排序演算法
- 【一起學習排序演算法】2 氣泡排序排序演算法
- 【一起學習排序演算法】4 插入排序排序演算法
- 演算法導論學習之三:排序之C語言實現:選擇排序,插入排序,歸併排序演算法排序C語言
- 【SQL 學習】排序問題之order by與索引排序SQL排序索引