氣泡排序,選擇排序,快速排序,堆排序詳解

2021-08-21 11:29:12 字數 3743 閱讀 5967

選擇排序,堆排序,快速排序都是不穩定的排序演算法。

a,氣泡排序

/** * 氣泡排序:每次將相鄰兩個數比較,如果不滿足排序條件則交換位置

* 比較次數:k>=n-1&&k<=(1/2)n(n-1)

* 時間複雜度:o(n)public

class

bubblesort

}//一趟完畢後,從第乙個元素開始,每相鄰兩個元素,前乙個元素小於後乙個元素,即a[2k]>a[2k+1](k=1,2,3...n/2-1)

if (swap == 0)//本趟已有序,結束排序

}//外層for結束

}//方法bubblesort結束

}b,選擇排序

/** * 選擇排序

* 基本思想:

* 每次從待排序記錄中選擇出關鍵字最小的記錄,並順序放在已排好序記錄序列的最後,

* 直到全部記錄序列排序完成為止。

* 適用場景:

* 由於選擇排序每趟總是從無序記錄中跳出關鍵字最小的記錄,因此適合從大量記錄中選擇一部分記錄的場景。

* 如從10000個記錄中選擇出關鍵字最小或最大的前10個記錄,就適宜採用選擇排序。

* 實現方法:

* 第一趟從n個無序記錄中選出關鍵字最小的記錄與第乙個記錄交換(此時第乙個記錄已有序);

* 第二趟再從第二個記錄開始的n-1個記錄中選擇出關鍵字最小的記錄與第二個記錄交換(此時前二個記錄已有序)....

* 如此下去,第i趟則從第i個記錄開始的n-i+1個記錄中選出關鍵字最小的記錄與第i個記錄交換 (此時前i個記錄已有序),

* 這樣n-1趟後前n-1個記錄已有序,無序記錄只剩乙個即第n個記錄,因此關鍵字小的前n-1個記錄已進入有序序列,

* 這第n個記錄比為關鍵字最大的記錄,所以無需交換即n個記錄已全部有序。

* 時間複雜度:

* 總比較次數:i:[1:n-1]*(n-i)=(1/2)n(n-1)]

* 因此時間複雜度為:o(n^2)

* 最好情況下是n個記錄一開始即為有序,移動次數為0,

* 最壞情況下是初始的n個記錄為逆序排列,即每一趟都要執行交換操作,總的移動次數為3(n-1)

* 所以直接選擇排序是一種不穩定的排序方法

* */

public

class

selectsort

}if(i!=j)}}

}c,快速排序

/** * 快速排序:核心演算法:劃分。

* 時間複雜度:

* o(nlogn)<=t(n)<=o(n^2)

* 排序過程:

* 任取其中乙個記錄(通常是第乙個記錄)為基準,

* 經過一趟交換之後,所有關鍵字比它小的記錄都交換到它的左邊,所有關鍵字比它大的都交換到它的右邊,

* 此時,基準記錄在序列中的最終位置就已經確定。

* 然後再分別對劃分到基準記錄左右兩部分區間的記錄序列重複上述過程,直到每一部分最終劃分為乙個記錄時為止。

*/public

class

quicksort

if (i < j)//再次判斷i,j的位置,

while (i < j && a[i] <= key)//i自左向右移動,直到找到大於a[0]的元素時,停止移動

if (i < j)//再次判斷i,j的位置,

}//while迴圈結束,一趟排序完成

return i;//返回基準記錄a[0]最終存放的位置。便於確定下次劃分位置。

}//方法partition結束

public

static

void

quicksort(int a, int s, int r)

}}d,堆排序

package wjh.mysort;

/** * 堆排序:

* 堆排序是一種樹形選擇排序,更確切的說是一種樹形選擇排序。

* 堆分為大根堆和小根堆

* 大根堆:父節點大於子節點的值

* 小根堆:父節點小於子節點的值

* * 堆排序思想:

* (以小根堆為例)

* 對n個待排序的記錄,首先根據各記錄的關鍵字按堆的定義排成乙個序列(即建立初始堆),從而由堆頂得到關鍵字最小

* 的記錄,然後將剩餘的n-1個記錄再調整成乙個新堆,即又由堆頂得到關鍵字最小的記錄,然後將剩餘的n-1個記錄再調整成乙個新堆,

* 即又由堆頂得到這n-1個記錄中最小關鍵字的記錄,如此反覆進行出堆和將剩餘記錄調整為堆的過程,當堆僅剩乙個記錄出堆時,則n個記錄已按

* 出堆次序排成有序序列。

* * 堆排序過程:

* (1)建立初始堆

* (2)調整成新堆

* 具體過程:

* 對n個關鍵字序列先將其建成堆(初始堆),然後執行n-1趟堆排序,第一趟先將序號為1的根節點與序號為n的節點進行交換

* (此時第n個節點用於儲存出堆節點),並調整此時的前n-1個節點為堆;第二趟將序號為1的根節點與序號為n-1的節點進行交換

* (此時第n-1個節點用於儲存出堆節點),並調整此時的前n-2個節點為堆......第n-1趟將序號為1的根節點與序號為2(因為(n-(n-1)+1)=2)

* 的節點進行交換(此時第2個節點用於儲存出堆節點)。由於此時待調整的對僅為序號為1的根節點故無需調整,整個堆排序過程結束。

* 至此。在一維陣列中的關鍵字已全部有序,但為逆序排列,故需要按公升序排列,則建大根堆,需要按降序排列則建小根堆。

* * 公升序需要建立大根堆,降序需要建立小根堆。

*我的理解:大根堆排序時出堆的時候是每次選最小的記錄出堆,這樣出堆的順序就為公升序,所以如果需要按公升序排列就需要建立大根堆。

* 小根堆相反。

* * 適用場景:

* 由於初始建堆所需比較的次數較多,因此堆排序不適合記錄較少的情況。

* 對大量記錄的排序來說堆排序是非常有效的。

* 並且,堆排序只需要乙個記錄的輔助空間(r[0]),即其空間複雜度為o(1)。

* * 堆排序是一種不穩定的排序演算法。

* 最壞情況下時間複雜度為o(nlogn),所以在最壞情況下堆排序的時間複雜度要低於快速排序。

*/public

class

helpsort

if (r[0] > r[j])

r[i]=r[j];//將關鍵字大的孩子節點r[j]調整至雙親節點r[i]

i=j;//定位於孩子節點繼續向下調整

}r[i]=r[0];//r[i]相當於r[j].將r[0]即r[s]調整到r[j]

}/**

* 堆排序演算法

*@param r 待排序的記錄陣列

*@param n 待排序的記錄數

*/public

static

void

heapsort(int r,int n)

for(i=n;i>1;i--)}}

初始堆建立過程示意圖

heapsort中呼叫heapadjust()建立初始堆的過程

將堆調整為新堆及堆排序過程示意圖

插入排序 選擇排序 氣泡排序 快速排序 堆排序

設待排序陣列為a n 1 直接插入排序 思想 將陣列a n 分為乙個有序區a 1 a i 和乙個無序區a i 1 a n 1 每一次將a i 1 插入有序區,形成乙個新的有序區,如此反覆。如下 include stdafx.h include using namespace std typedef ...

Python氣泡排序 快速排序 堆排序

氣泡排序 def bubble sort array,n for i in range n for j in range 1 n i if array j 1 array j array j 1 array j array j array j 1 快速排序 def quick sort array,...

氣泡排序,選擇排序,快速排序

1.氣泡排序 氣泡排序 bubble sort 最為簡單的一種排序,通過重複走完陣列的所有元素,通過打擂台的方式兩個兩個比較,直到沒有數可以交換的時候結束這個數,再到下個數,直到整個陣列排好順序。因乙個個浮出所以叫氣泡排序。雙重迴圈時間o n 2 void bubblesort int arr in...