演算法邏輯思維(3)排序

2021-10-10 05:11:08 字數 4629 閱讀 6996

3.排序:經典排序演算法原理解析與優劣對比

二分查詢要求原陣列必須有序

由無序到有序,是演算法領域常見的一類問題,常用的排序演算法有氣泡排序、插入排序、歸併排序以及快速排序

3.1什麼是排序問題

排序–讓一組無序資料變成有序的過程,一般預設這裡的有序都是從小到大的排列順序

衡量乙個排序演算法的優劣:

1.時間複雜度–具體包括,最好時間複雜度、最壞時間複雜度以及平均時間複雜度

2.空間複雜度–如果空間複雜度為1,也叫做原地排序

3.穩定性–指相等的資料物件,在排序之後,順序是否能保證不變

3.2氣泡排序

3.2.1氣泡排序的原理

從第乙個資料開始,一次比較相鄰元素的大小。如果前者大於後者,則進行交換操作,把大的元素往後交換。通過多輪迭代,直到沒有交換操作為之。

3.2.2氣泡排序效能

最好時間複雜度是o(n)

也就是當輸入陣列剛好是順序的時候,只需要挨個比較一遍就可以

氣泡排序的最壞時間複雜度是o(nn)

也就是當陣列剛好是完全逆序的時候,每輪(排序都)需要挨個比較n次,並且重複n次

當輸入陣列雜亂無章時,它的平均複雜度是o(nn)

空間複雜度為o(1)

public

static

void

main

(string[

] args)

;system.out.

println

("原始資料"

+arrays.

tostring

(arr));

boolean isasc =

true

;for

(int i =

1; i < arr.length; i++)}

}}

3.3插入排序

3.3.1插入排序的原理

選取未排序的元素,插入到已排序區間的合適位置,直到未排序區間為空。

3.3.2插入排序的效能

插入排序最好的時間複雜度是o(n)

即當陣列剛好是完全順序的時候,每次只用比較一次就能找到正確的位置區間

插入排序最壞時間複雜度則需要o(nn)

即當陣列剛好是完全逆序時,每次都要比較n次才能找到正確的位置區間

插入排序的平均時間複雜度是o(nn)。因為往陣列中插入乙個元素的平均時間複雜度為o(n)

而插入排序可以理解為重複n次的陣列插入操作

空間複雜度為o(1)。氣泡排序過程當中,當元素相同時不做交換,所以氣泡排序是穩定的排序演算法。**如下:

public

static

void

main

(string[

] args)

; system.out.

println

("原始資料: "

+ arrays.

tostring

(arr));

for(

int i =

1; i < arr.length; i++

)else

} arr[j +1]

= temp;

} system.out.

println

("插入排序: "

+ arrays.

tostring

(arr));

}

3.3.3插入排序和氣泡排序演算法的異同點

相同點插入排序和氣泡排序的平均時間複雜度都是o(n*n),而且都是穩定的排序演算法,都屬於原地排序

差異點氣泡排序每輪的交換操作是動態的,所以需要三個賦值操作才能完成

插入排序每輪的交換動作會固定待插入的資料,因此只需要一步賦值操作

3.4歸併排序

3.4.1歸併排序原理

public

static

void

main

(string[

] args)

;int

tmp =

newint

[arr.length]

;custommergesort

(arr,tmp,

0,arr.length -1)

; system.out.

println

(arrays.

tostring

(arr));

}public

static

void

custommergesort

(int

a,int[

] tmp,

int start,

int end)

}public

static

void

customdoublemerge

(int

a,int[

] tmp,

int left ,

int mid,

int right)

while

(p1 <= mid)

tmp[k++

]= a[p1++];

while

(p2 <= right)

tmp[k++

]= a[p2++];

for(

int i = left;i <= right;i++

) a[i]

= tmp[i];}

}

3.4.2歸併排序的效能

歸併排序採用了二分的迭代方式,複雜度是logn

每次的迭代,需要對兩個有序陣列進行合併,這樣的動作在o(n)的時間複雜度下就可以完成

歸併排序的複雜度就是二者的乘積o(nlogn)

歸併排序最好、最壞、平均時間複雜度都是o(nlogn)

歸併排序的空間複雜度為o(n)

3.5快速排序

3.5.1快速排序原理

快速排序法的遠離也是分治法。他的每輪迭代,會選取陣列中任意乙個資料作為分割槽點,將小於它的元素放在它的左側,大於它的放在它的右側。再利用分治思想,繼續分別對左右兩側進行同樣的操作,直至每個區間縮小為1,則完成排序。

public

static

void

main

(string[

] args)

; system.out.

println

("原始資料: "

+ arrays.

tostring

(arr));

customquicksort

(arr,

0, arr.length -1)

; system.out.

println

("快速排序: "

+ arrays.

tostring

(arr));

}public

void

customquicksort

(int

arr,

int low,

int high)

i = low;

j = high;

temp = arr[low]

;while

(i < j)

// 再看左邊,依次往右遞增

while

(temp >= arr[i]

&& i < j)

t = arr[j]

; arr[j]

= arr[i]

; arr[i]

= t;

} arr[low]

= arr[i]

; arr[i]

= temp;

// 遞迴呼叫左半數組

customquicksort

(arr, low, j -1)

;// 遞迴呼叫右半陣列

customquicksort

(arr, j +

1, high)

;}

3.5.2快速排序的演算法效能

在快排的最好時間的複雜度下,如果每次選取區分點時,都能選中中位數,把陣列等分成兩個,此時時間複雜度是o(nlogn)

在最壞的時間複雜度下,也就是如果每次分割槽都選中了最小值或最大值,得到不均等的兩組,就需要n次的分割槽操作,每次分割槽平均掃瞄n/2個元素,此時時間複雜度退化為o(nn)

快速排序法平均的時間複雜度是o(nlogn)

快速排序法的空間複雜度為o(1),快速排序涉及交換操作,所以是不穩定的排序演算法

3.5.3排序演算法的效能分析

排序最暴力的方法,時間複雜度是o(nn)

利用歸併排序能讓時間複雜度降低到o(nlogn)

歸併排序需要額外開闢臨時空間 :

為了保證穩定性,另一方面則是在歸併時,由於在陣列中插入元素導致了資料挪移的問題。

為了規避因此而帶來的時間損耗,此時我們採用快速排序。通過交換操作,可以解決插入元素導致的資料挪移問題,而且降低了不必要的空間開銷。但是由於其動態二分的交換資料,導致了由此得出的排序結果並不穩定。

3.6總結

如果對資料規模比較小的資料進行排序,可以選擇時間複雜度為o(n*n)的排序演算法。

但對資料規模比較大的資料進行排序,就需要選擇時間複雜度為o(nlogn)的排序演算法了。

3 排序演算法 歸併排序

問題描述 歸併排序演算法對下列例項排序,寫出基於歸併排序演算法對下面例項進行排序的具體過程。a 48,12,61,3,5,19,32,7 解題思想 將n個元素分成2個子集合,分別對子集合進行排序,最終將排好序的子集合合併為有序集合。n 1是中止。如下 include include using na...

演算法3 排序 簡單選擇排序

基本思想 在要排序的一組數中,選出最小的乙個數與第乙個位置的數交換 然後在剩下的數當中再找最小的與第二個位置的數交換,如此迴圈到倒數第二個數和最後乙個數比較為止。選擇排序的思想其實和氣泡排序有點類似,都是在一次排序後把最小的元素放到最前面。但是過程不同,氣泡排序是通過相鄰的比較和交換。而選擇排序是通...

資料結構3 排序演算法

氣泡排序 演算法描述 排序問題是基本演算法,主要有冒泡演算法 插入排序以及選擇排序演算法。冒泡演算法是對整個列進行多次遍歷迴圈,直至將所有的數都比較一遍,每次迴圈都能產生乙個最大數放置於後面,這樣需要兩層迴圈 外層控制次數,內層控制單次冒泡,內層針對的是相鄰裡兩個進行比較的迴圈。using syst...