本篇博文旨在介紹排序演算法中的交換排序;介紹了氣泡排序和快速排序的基本思想;介紹了氣泡排序和快速排序的幾種實現方法;從時間複雜度和空間複雜度進行了分析;並用c++實現了氣泡排序和快速排序
依次比較相鄰的兩個數,如果前者比後者大,就進行交換。一輪下來可以將大的元素先放到最右邊的位置。然後縮小區間,再次從頭開始第二輪的氣泡排序,這一次將次大的數放到相應位置。再次從頭冒泡,直到區間只有1個數。
按照公升序舉例
1、比較相鄰兩個數的大小,如果前面的數比後面的大,就進行交換
2、如果沒有比較的區間的尾部,依次向後冒泡
3、這一輪會將最大的數冒到區間的最右邊,然後區間右邊減少乙個數,重複上述步驟
4、直到區間縮小為1
當排序到一定趟數時,其剩下的元素可能已經有序,不需要進行冒泡了
這時,再次冒泡只會白白的浪費時間
解決方法只需要加乙個標誌位,用來判斷該次排序有沒有進行交換資料。
如果一趟排序下來並沒有進行資料的交換,就表示剩下的元素已經有序了,直接結束排序
從演算法中,我們可以分析出,氣泡排序第一趟排序排n-1次,第二趟排n-2,第三趟n-3....
所以其時間複雜度為o(n* n)
優化後,雖然一定程度上減少了資料的比較次數,在最好情況(有序)下,時間複雜度是o(n)
但是在最壞情況(逆序)下,仍是o(n* n)的演算法
所以優化並不能減少氣泡排序的數量級
#pragma once
#includeusing namespace std;
void print(int* arr, size_t n)
cout << endl;
}//公升序
templatestruct greater
};//降序
templatestruct less
};//氣泡排序
template>
void bubblesort(t* arr,size_t n)
} //表示已經有序,直接返回
if (false == true)
return; }}
void testbubblesort()
; bubblesort>(arr, 10);
cout << "氣泡排序:" << endl;
print(arr, 10);
}
每次排序將乙個數放到合適的位置上,並以此位置劃分成兩個區間;
達到左邊的數都比該數小,右邊的數都比該數大;
然後遞迴進行兩個區間的排序
演算法步驟
1、用左指標left和右指標right兩個值表示著排序的區間,並將右指標right所指向的值存為key值,也就是當前的坑
2、從左指標向右找比key值大的數,找到了停止,將左指標指向的數填入坑中,然後讓左指標指向的數成為新坑
3、接下來從右指標向左找比key值小的數,找到了停止,將右指標指向的數填入新的坑中
4、反覆第2、3步,直到兩個指標相遇
5、將第1步保留的key值放入最後乙個坑中,並以此劃成兩個區間
**實現
//方法1:挖坑法
int partsort1(int* a, int left, int right)
a[left] = key;
return left;
}
演算法步驟
1、用左指標left和右指標right兩個值表示著排序的區間
2、從左指標向右找比key值大的數,找到了停止
3、接下來從右指標向左找比key值小的數,找到了停止
4、交換左指標和右指標數的指向
5、反覆第2、3、4步,直到兩個指標相遇
**實現
int partsort(int* arr, int left, int right)
swap(arr[left],arr[key]);
return left;
}
演算法步驟
1、cur指向left,prev指向cur的前乙個
2、當cur遇到的數比key值(最右邊的值)大時,繼續往前走;
若cur遇到的值比key值小,讓prev向前走一步並和cur進行交換
3、cur走到最右邊時,讓prev向前走一步並和cur進行交換
4、將區間劃分為兩個部分,直到區間內只有乙個數
**實現
//方法3:前後指標法
int partsort3(int* a, int left, int right)
if (++prev != cur)
std::swap(a[prev], a[cur]);
return prev;
}
整趟排序利用單趟排序的返回值將其分成兩個區間
然後分別對兩個區間進行快速排序
void quicksort(int* a, int left, int right)
}
快速排序採用了二分的思想
最好情況,每次劃分區間都將區間平分成兩份,此時的時間複雜度為o(n* logn)
最壞情況,每次劃分區間,都導致其中乙個區間為空,此時的時間複雜度為o(n* n)
但是一般情況下,我們認為快速排序的時間複雜度為o(n* logn)
空間複雜度為o(logn)
由於快速排序這裡採用了遞迴的演算法,當對小區間進行快速排序時,反不如直接插入排序更為高效
所以當元素個數小於一定的數量時,採用直接插入排序
**實現
void quicksort(int* a, int left, int right)
int mid = partsort3(a, left, right);
quicksort(a, left, mid - 1);
quicksort(a, mid + 1, right);
}}
之前我們分析,快速排序最好的情況就是每次劃分區間,兩邊的區間大小是一致的
所以我們通過在左,右,中三個下標中找到不大不小的那個數,將其放到最右邊作為key值進行區間的劃分
從而盡可能的保證了劃分後的兩個區間大小相差不會很大,從而提高了快速排序的效率
**實現
//三數取中法
int getmidindex(int* a, int left, int right)
else//mid left
}
例如挖坑法,其他方法也加到開頭即可
//方法1:挖坑法
int partsort1(int* a, int left, int right)
a[left] = key;
return left;
}
之前實現快速排序的單趟排序都是運用了遞迴,一聽到遞迴這兩個字就應該考慮到,當數量大時可能到時棧溢位的問題
因為遞迴就是一種壓棧的過程,因此我們可以用庫中自帶棧來實現非遞迴的快速排序
從而減少了遞迴導致的呼叫函式的開銷,效率也大大提高
**實現
#include//非遞迴
void quicksortnonr(int* a, size_t n)
if (mid + 1 < right)}}
排序演算法 交換排序
交換排序的基本思想 兩兩比較待排序元素的關鍵字,發現兩個元素的次序相反時則進行交換,直到沒有反序的元素為止。1.氣泡排序 交換排序 演算法 氣泡排序 bubble sort 輸入 待排序元素的陣列,待排序元素個數 輸出 原理 通過無序區中相鄰元素間關鍵字的比較和位置的交換,使關鍵字最小的元素如氣泡一...
排序演算法 交換排序
基本思想 在乙個待排序序列中,兩兩比較元素的排序碼,如果不滿足次序要求則進行交換,直到整個排序序列滿足要求。思想 對待排序序列從前向後,依次比較相鄰元素的排序碼,若發生逆序,則進行交換。實現 include void bubblesort int p,int n if flag 減少不必要的比較 r...
交換排序演算法
快速排序 為啥叫快速排序,因為速度快,效率高 1.先找乙個數作為基準。作為基準的這個數,一趟排下來,左邊的數必小於它,右邊的數必大於它,也就是說,它找到了自己的位置。2.將兩個指標i,j分別指向表的起始 基準 和最後的位置。3.比較j指標的數字是否小於基準,j 直到j小於基準,交換位置 4.比較i指...