幾種常見排序演算法

2021-08-14 16:14:42 字數 3994 閱讀 3867

幾種常見排序演算法

1氣泡排序(bubble sort)

氣泡排序思路:

將序列當中的左右元素,依次比較,保證右邊的元素始終大於左邊的元素;( 第一輪結束後,序列最後乙個元素一定是當前序列的最大值;)

對序列當中剩下的n-1個元素再次執行步驟1。

3. 對於長度為n的序列,一共需要執行n-1輪比較 

**實現:

for (i = 0; i < n; i++)

}   

氣泡排序是穩定的。演算法時間複雜度是o(n^2),空間複雜度o(1).  

2直接選擇排序(selection sort)    

直接選擇排序的基本思想:比較+交換。

從待排序序列中,找到關鍵字最小的元素;

如果最小元素不是待排序序列的第乙個元素,將其和第乙個元素互換;

從餘下的 n - 1 個元素中,找出關鍵字最小的元素,重複(1)、(2)步,直到排序結束。

選擇排序通過兩層迴圈實現。

第一層迴圈:依次遍歷序列當中的每乙個元素

第二層迴圈:將遍歷得到的當前元素依次與餘下的元素進行比較,符合最小元素的條件,則交換。

直接選擇排序是不穩定的:演算法的時間複雜度為o(n^2),空間複雜度是o(1).  

**實現:

def select_sort(l):

#依次遍歷序列中的每乙個元素

for x in range(0,len(l)):

#將當前位置的元素定義此輪迴圈當中的最小值

minimum = l[x]

#將該元素與剩下的元素依次比較尋找最小元素

for i in range(x+1,len(l)):

if l[i] < minimum:

temp = l[i];

l[i] = minimum;

minimum = temp

#將比較後得到的真正的最小值賦值給當前位置

l[x] = minimum

3直接插入排序(insertion sort)    

直接插入排序的核心思想就是:將陣列中的所有元素依次跟前面已經排好的元素相比較,如果選擇的元素比已排序的元素小,則交換,直到全部元素都比較過。

直接插入排序是穩定的。演算法時間複雜度是o(n^2),空間複雜度是o(1).   

直接插入排序可以用兩個迴圈完成:

第一層迴圈:遍歷待比較的所有陣列元素

第二層迴圈:將本輪選擇的元素(selected)與已經排好序的元素(ordered)相比較。

如果:selected > ordered,那麼將二者交換

**實現:

def insert_sort(l):

#遍歷陣列中的所有元素,其中0號索引元素預設已排序,因此從1開始

for x in range(1,len(l)):

#將該元素與已排序好的前序陣列依次比較,如果該元素小,則交換

#range(x-1,-1,-1):從x-1倒序迴圈到0

for i in range(x-1,-1,-1):

#判斷:如果符合條件則交換

if l[i] > l[i+1]:

temp = l[i+1]

l[i+1] = l[i]

l[i] = temp

4堆排序   

堆排序是一種樹形選擇排序,在排序過程中,將a[n]看成是完全二叉樹的順序儲存結構,利用完全二叉樹中雙親結點和孩子結點之間的內在關係來選擇最小的元素。  

堆排序是不穩定的。演算法時間複雜度o(nlog n),空間複雜度是o(1).  

1.首先將序列構建稱為大頂堆;

2.取出當前大頂堆的根節點,將其與序列末尾元素進行交換;

3.對交換後的n-1個序列元素進行調整,使其滿足大頂堆的性質;

4.重複2.3步驟,直至堆中只有1個元素為止   

**實現:

void  heapsort(recordtype  r,int length)

} /* heapsort */ 

5歸併排序   

採用分治法演算法, 歸併排序實際上就是兩個操作,拆分+合併, 

分解----將序列每次折半拆分

合併----將劃分後的序列段兩兩排序合併

歸併排序是穩定的:其時間複雜度無論是在最好情況下還是在最壞情況下均是o(nlog2n), 空間複雜度是o(1). 

合併演算法實現:

void merge ( recordtype r1,  int low,   int mid,   int high,  recordtype  r)

else

++k ;

}if ( i<=mid )   

r[k..high] =r1[i..mid];

if ( j<=high )

r[k..high] =r1[j..high];

} 6快速排序    

快速排序是對氣泡排序的一種本質改進。

它的基本思想(挖坑填數+分治法)是通過一趟掃瞄後,使得排序序列的長度能大幅度地減少。在氣泡排序中,一次掃瞄只能確保最大數值的數移到正確位置,而待排序序列的長度可能只減少1。快速排序通過一趟掃瞄,就能確保某個數(以它為基準點吧)的左邊各數都比它小,右邊各數都比它大。然後又用同樣的方法處理它左右兩邊的數,直到基準點的左右只有乙個元素為止。 

用偽**描述如下:

1.i =l; j = r; 將基準數挖出形成第乙個坑a[i]。

2.j--由後向前找比它小的數,找到後挖出此數填前乙個坑a[i]中。

3.i++由前向後找比它大的數,找到後也挖出此數填到前乙個坑a[j]中。

4.再重複執行2,3二步,直到i==j,將基準數填入a[i]中

快速排序是不穩定的。最理想情況演算法時間複雜度o(nlog2n),最壞o(n ^2),空間複雜度為o(nlog2n)。

**實現:

int quicksort(vector&v, int left, int right)

v[low] = v[high];

while(low < high && v[low] < key)

v[high] = v[low];

}v[low] = key;

quicksort(v,left,low-1);

quicksort(v,low+1,right);}}

7希爾排序 (shell)  

在直接插入排序演算法中,每次插入乙個數,使有序序列只增加1個節點,並且對插入下乙個數沒有提供任何幫助。如果比較相隔較遠距離(稱為增量)的數,使得數移動時能跨過多個元素,則進行一次比較就可能消除多個元素交換。

希爾排序的演算法思想:將待排序陣列按照步長gap進行分組,然後將每組的元素利用直接插入排序的方法進行排序;每次將gap折半減小,迴圈上述操作;當gap=1時,利用直接插入,完成排序。

希爾排序是穩定的:演算法時間複雜度是o(n^2),空間複雜度是o(1).   

希爾排序的總體實現應該由三個迴圈完成:

第一層迴圈:將gap依次折半,對序列進行分組,直到gap=1

第二、三層迴圈:也即直接插入排序所需要的兩次迴圈。具體描述見上。

**實現:

def insert_shell(l):

#初始化gap值,此處利用序列長度的一般為其賦值

gap = (int)(len(l)/2)

#第一層迴圈:依次改變gap值對列表進行分組

while (gap >= 1):

#下面:利用直接插入排序的思想對分組資料進行排序

#range(gap,len(l)):從gap開始

for x in range(gap,len(l)):

#range(x-gap,-1,-gap):從x-gap開始與選定元素開始倒序比較,每個比較元素之間間隔gap

for i in range(x-gap,-1,-gap):

#如果該組當中兩個元素滿足交換條件,則進行交換

if l[i] > l[i+gap]:

temp = l[i+gap]

l[i+gap] = l[i]

l[i] =temp

#while迴圈條件折半

gap = (int)(gap/2)

幾種常見排序演算法

1氣泡排序 bubble sort 氣泡排序思路 1.將序列當中的左右元素,依次比較,保證右邊的元素始終大於左邊的元素 第一輪結束後,序列最後乙個元素一定是當前序列的最大值 2.對序列當中剩下的n 1個元素再次執行步驟1。3.對於長度為n的序列,一共需要執行n 1輪比較 實現 for i 0 i n...

幾種常見排序演算法

以下內容包括 氣泡排序,選擇排序,桶排序 一 氣泡排序 bubblesort public class bubblesort int temp 0 for int i 0 i1 i system.out.println arrays.tostring arr 用arrays類中的tostring方法...

幾種常見的排序演算法

氣泡排序演算法的運作如下 1 比較相鄰的元素。如果第乙個比第二個大,就交換他們兩個。2 對每一對相鄰元素作同樣的工作,從開始第一對到結尾的最後一對。這步做完後,最後的元素會是最大的數。3 針對所有的元素重複以上的步驟,除了最後乙個。4 持續每次對越來越少的元素重複上面的步驟,直到沒有任何一對數字需要...