交換排序(氣泡排序&&快速排序)
寫在前面
氣泡排序
氣泡排序其實是非常簡單,他就是把一個數與他的前一個數在比較與交換的過程;
這個簡單,我就直接上程式碼了:
版本一:
//最簡單直接,但是效率不高
void BulleSort(int* array, int size)
{
for(size_t i = 0; i < size; i++)
{
for(size_t j = 0; j < size - i - 1; j++)
{
if(array[j] > array[j + 1])
swap(array [j], array[j + 1]);
}
}
}
版本二:
void BulleSort(int* array, int size)
{
int j, k;
bool flag;
flag = true;
k = size;
while(flag)
{
flag = false;
for(size_t j = 1; j < size; j++)
{
if(array[j] < array[j - 1])
{
swap(array [j], array[j - 1]);
flag = true;
}
}
k--;
}
}
快速排序
快排的答題思路就是這個樣子,但是我們需要進一步進行深挖:
快排第一種:
左右指標法:
1. 選好一個基準值以後,左指標從左向右找第一個大於基準值的數,找到後停下;
2. 右指標從右向左找第一個小於基準值的數,找到後停下;
3. 然後進行左右交換;
4. 遞迴式的尋找,直到有序
int PortSort(int* array, int left, int right)
{
int mid = GetMidIndex(array, left, right);
swap(array[mid], array[right]);
assert(array);
int key = right;
while(left < right)
{
while(array[left] < array[key])
left++;
while(array[right] > array[key])
right--;
if(array[left] != array[right])
swap(array[left], array[right]);
}
swap(array[left], array[key]);
return left;
}
快排2
挖坑法
1. 其實和左右指標差不多,就是把資料拿出來了,新資料直接放裡面就可以了;
2. 從左向右遍歷,找到大於基準值的就放到基準值的位置;
3. 從右向左遍歷,找到小於基準值的就放到上一個空位置;
4. 迴圈遞迴就可以;
int PortSort(int* array, int left, int right)
{
int mid = GetMidIndex(array, left, right);
swap(array[mid], array[right]);
assert(array);
int hole = array[right];
while(left < right)
{
while(array[left] < hole)
left++;
if(left < right)
array[right--] = array[left];
while(array[right] > hole)
right++;
if(left < right)
array[left++] = array[right];
}
array[left] = hole;
return left;
}
快排3
前後指標法:
1. 用兩個指標標識2個數;
2. 當第二個指標小於基準值並且++第一個指標後不等於第二個指標,就說明第一個指標已經是大於基準值的了;其實可能折磨描述不太好理解,下面配上程式碼,就一目瞭然了;
3. 然後在自增第二個指標;
4. 依次迴圈遞迴即可;
int PortSort3(int *array, int left, int right)
{
int mid = GetMidIndex(array, left, right);
swap(array[mid], array[right]);
int pCur = left;
int pPre = pCur - 1;
int key = array[right];
while(pCur != right)
{
if(array[pCur] < key && array[++pPre] != array[pCur])
swap(array[pPre], array[pCur]);
++pCur;
}
swap(array[++pPre], array[pCur]);
}
快排的優化
- 我們都知道在快排中,我們要選取基準值,如果基準值選的是最中間的值,那麼我們的排序效率將會比較高,但是如果選個最小的值,那麼它快排的效率將完全體現不出來了,所以針對基準值的取法,進行優化是一件很重要的事;
//優化1: 三數取中法,不管什麼情況下,返回去的都是大小適中的值
int GetMidIndex(int* array, int left, int right)
{
int mid = left + ((right - left) >> 1);
if (array[left] < array[mid])
{
if (array[mid] < array[right])
return mid;
else if (array[left] < array[right])
return right;
else
return left;
}
else
{
if (array[mid] > array[right])
return mid;
else if (array[left] > array[right])
return right;
else
return left;
}
}
- 當劃分的子序列很小的時候(一般認為小於13個元素左右時),我們再使用快速排序對這些小序列排序反而不如直接插入排序高效。因為快速排序對陣列進行劃分最後就像一顆二叉樹一樣,當序列小於13個元素時我們再使用快排的話就相當於增加了二叉樹的最後幾層的結點數目,增加了遞迴的次數。所以我們在當子序列小於13個元素的時候就改用直接插入排序來對這些子序列進行排序。
void InsertSort(int *array, int n)
{
int end = 0;
for (size_t i = 1; i < n; i++)
{
int tmp = array[i];
end = i - 1;
while (end >= 0)
{
if (array[end] > tmp)
{
array[end + 1] = array[end];
--end;
}
}
array[end + 1] = tmp;
}
}
資料量太大時可能造成遞迴的深度太大,效率就太低,所以可以利用棧來實現
““
void QuickSortNodeR(int* array, int left, int right)
{
stack s;
s.push(right);
s.push(left);while (!s.empty())
{
int start = s.top();
s.pop();
int end = s.top();
s.pop();if (end > start) { int div = PortSort1(array, start, end); s.push(div - 1); s.push(start); s.push(right); s.push(div + 1); }
}
}
“`
相關推薦
交換排序(氣泡排序—改進、快速排序)
【氣泡排序(改進版本)】 複雜度:最好情況O(n),最壞O(n^2);演算法穩定 int a[10]={1,3,2,4,6,5,9,7,8,0}; int flag=9, last_flag=9;
多關鍵字排序(一個快速排序加兩個氣泡排序)
#include <stdio.h> #include <stdlib.h> typedef struct { char name[20]; float math,english,computer; float total; }Student; void
排序演算法之快速排序,氣泡排序用python程式碼實現
一、快速排序 1.在列表中選出一個基準數(通常為列表的第一個數) 2.將列表中小於基準數的資料移到基準列表的左邊,將大於基準數的資料移到基準數的右邊 3.對於基準數左,右兩邊的列表,不斷重複以上兩個過程,直到每個子集只有一個元素, 即為全部有序的. def qu
氣泡排序法、選擇排序法、快速排序法三者的效率對比,包括陣列的儲存與載入
排序演算法: // 冒泡 void sorta(int array[], int n) { for (int i = 0; i < n; i++) { for (int t = i + 1; t < n; t++) { if (array[
幾種常用的排序演算法(快速排序,希爾排序,堆排序,選擇排序,氣泡排序)
1、歸併排序 基本原理:歸併排序也稱合併排序,其演算法思想是將待排序序列分為兩部分,依次對分得的兩個部分再次使用歸併排序,之後再對其進行合併。操作步驟如下。(1)將所要進行的排序序列分為左右兩個部分,如果要進行排序的序列的起始元素下標為first,最後一個元素的
java排序演算法-比較快速排序,氣泡排序,雙向氣泡排序的執行效率
快速排序 原理是找出一個元素(理論上可以隨便找一個)作為基準(pivot),然後對陣列進行分割槽操作,使基準左邊元素的值都不大於基準值,基準右邊的元素值 都不小於基準值,如此作為基準的元素調整到排序後的正確位置。遞迴快速排序,將其他n-1個元素也調整到排序後的正確位置。
python的氣泡排序法和快速排序法
快速排序法的核心在於:1.先從數列中取出一個數作為基準數。2.分割槽過程,將比這個數大的數全放到它的右邊,小於或等於它的數全放到它的左邊。3.再對左右區間重複第二步,直到各區間只有一個數。 #氣泡排序法 def bubling_sort(list): for i i
實驗六:排序演算法應用 1.錄入學生基本資訊 2、直接插入排序 3、氣泡排序 4、快速排序 5、簡單選擇排序 6、堆排序
/*實驗六:排序演算法應用 內容: 給出n個學生的考試成績表,每條記錄由學號、姓名和分數和名次組成,設計演算法完成下列操作: (1)設計一個顯示對學生資訊操作的選單函式如下所示: *************************1、錄入學生基本資訊2、直接插入排序3、氣泡
排序算法——快速排序
ron 再次 一個數 規模 color san 遞歸 oid urn 算法思想: 分治+挖坑填數 分治思想 將原問題分解成若幹規模更小但是結構和原問題相同的子問題。遞歸求解子問題,然後解出原問題。 快排算法思想 ①選擇數組中第一個數作為基數,然後
排序5:快速排序
元素 swap while 實例 pes 步驟 等於 自己 data http://blog.csdn.net/morewindows/article/details/6684558 選擇一個基準元素,通常選擇第一個元素或者最後一個元素,通過一趟掃描,將待排序列分成兩部
排序算法-快速排序
args mob 大於 right cnblogs 指針 sort arr num 參考博文:http://www.cnblogs.com/MOBIN/p/4681369.html 快速排序是冒泡排序的改進版,也是最好的一種內排序,在很多面試題中都會出現 思想:
Java常用的八種排序演算法與程式碼實現(二):歸併排序法、快速排序法
注:這裡給出的程式碼方案都是通過遞迴完成的 --- 歸併排序(Merge Sort): 分而治之,遞迴實現 如果需要排序一個數組,我們先把陣列從中間分成前後兩部分,然後對前後兩部分進行分別排序,再將排好序的數組合並在一起,這樣整個陣列就有序了 歸併排序是穩定的排序演算法,時間
快速排序和隨機快速排序
轉載http://blog.csdn.net/always2015/article/details/46523531 一、問題描述 實現對陣列的普通快速排序與隨機快速排序 (1)實現上述兩個演算法 (2)統計演算法的執行時間 (3)分析效能差異,作出總結 二、演
經典排序演算法之--快速排序
快速排序是一種高效但不穩的排序演算法,不穩性取決於比較基數的選擇帶有隨機性,其排序原理應用百度百科如下: 設要排序的陣列是A[0]……A[N-1],首先任意選取一個數據(通常選用陣列的第一個數)作為關鍵資料,然後將所有比它小的數都放到它前面,所有比它大的數都放到它後面,這個過程稱為一趟快速排
c#程式碼實現排序演算法之快速排序
快速排序的平均時間複雜度為O(nlog2n),最好時間複雜度為O(nlog2n),最壞時間複雜度為O(n²),空間複雜度為O(log2n),是一種不穩定的演算法。 1.劃分:選定一個記錄作為軸值,以軸值為基準將整個序列劃分為兩個子序列r(1)…r(i-1)和r(i+1)…r(n)
排序演算法二--快速排序
快速排序(Quicksort) 基本思想:(分治) 先從數列中取出一個數作為key值; 將比這個數小的數全部放在它的左邊,大於或等於它的數全部放在它的右邊; 對左右兩個小數列重複第二步,直至各區間只有1個數。 輔助理解:挖坑填數
演算法導論 第七章:快速排序 筆記(快速排序的描述、快速排序的效能、快速排序的隨機化版本、快速排序分析)
快速排序的最壞情況時間複雜度為Θ(n^2)。雖然最壞情況時間複雜度很差,但是快速排序通常是實際排序應用中最好的選擇,因為它的平均效能很好。它的期望執行時間複雜度為Θ(n lg n),而且Θ(n lg n)中蘊含的常數因子非常小,而且它還是原址排序的。 快速排序是一種排序演算法,對包含n個數的
基礎演算法--排序:之快速排序
與簡單排序不同,快序排序所需的比較次數較少,是內部排序中速度較快的一種排序方法。 演算法思想: 分-------------- 將待排序集合劃分為2部分 (一部分小於準則值,一部分大於等於準則值) &n
常見排序演算法之快速排序
文章目錄 前言 思路 實現過程 基本演算法 切分方法 複雜度分析 最優時間複雜度的數學證明 演算法改進 切換到插入排序 三取樣切分 三向
PHP排序演算法之快速排序
原理:找到當前陣列中的任意一個元素(一般選擇第一個元素),作為標準,新建兩個空陣列left、rignt,遍歷整個陣列元素,如果遍歷到的元素比當前的元素小就放到陣列left,比當前的元素大放到rignt,然後再對新陣列進行同樣的操作。 遞迴:遞迴是一種函式呼叫自身的機制。遞迴必須要有邊界條件,也就是遞迴出口(