JAVA數據結構與算法(三)、排序算法

排序算法

序也稱排序算法(Sort Algorithm)排序是將數據,依指定的順序進行排過程。java

序的分類:redis

1) 部排序:指將須要處理的全部數據都加內部存儲器中進行排序。算法

2) 外部排序法:數據量過大,沒法所有加載到中,須要藉助外部存儲進行排序數組

3) 常見的排序算法分類(右圖):緩存

l算法的時間複雜度

量一個程(算法)行時種方法

1) 後統計的方
這種方法可 , 是有兩個 問題
一是要想對設計的算法的運行性能進行評測 須要 際運 行該程序;
二是所得時間的統計量依賴於計算機的硬件、軟件等環境因 , 這種方式,要在同一臺計算機的相同狀態下運行,才能比較哪一個算法 度更快
 
2) 事前估 算的方
經過分析某個算法的 時間複雜度 來判斷哪一個算法更優 .

間頻

間頻:一個算法花費的時間與算法中語句的執行次數成正比例,哪一個算法中語句執行次數多,它花費時間就多。一個算法中的語句執行次數稱爲語句頻度或時間頻度。記爲T(n)函數

例說明-基本案例

1-100全部數字之, 咱們設計兩種算法:性能

T(n)=n+1;測試

T(n)=1;優化

舉例說明-忽略常數項

 

T(n)=2n+20spa

T(n)=2*n

T(3n+10)

T(3n)

1

22

2

13

3

2

24

4

16

6

5

30

10

25

15

8

36

16

34

24

15

50

30

55

45

30

80

60

100

90

100

220

200

310

300

300

620

600

910

900

結論:

1) 2n+20 2n 隨着 n 變大 執行曲線無限接近 , 20 能夠忽略
2) 3n+10 3n 隨着 n 變大 行曲線無限接近 , 10 以忽略
 

忽略低次項

 

T(n)=2n^2+3n+10

T(2n^2)

T(n^2+5n+20)

T(n^2)

1

15

2

26

1

2

24

8

34

4

5

75

50

70

25

8

162

128

124

64

15

505

450

320

225

30

1900

1800

1070

900

100

20310

20000

10520

10000

 

結論:

1) 2n^2+3n+10 2n^2 隨着 n 變大 , 行曲線無限接近 , 能夠忽略 3n+10
2) n^2+5n+20 n^2 隨着 n 變大 , 執行曲線無限接近 , 能夠忽 5n+20
 

時間複雜度

1) 般狀況下,算法中的基本操做語句的重複執行次數是問題規模 n 的某個函數,用 T(n) 表示,如有某個輔助函數 f(n) ,使得當 n 趨近於無窮大時, T(n) / f(n) 的極限值爲不等於零的常數,則稱 f(n) T(n) 的同數量級函數。記做 T(n)= ( f(n) ) ,稱O ( f(n) )  爲算法的漸進時間複雜度,簡稱時間複雜度
2) T(n ) 不一樣,但時間複雜度可能相同。 如: T(n)= n²+7n+6 T(n)= 3n²+2n+2 它們的 T(n)  不一樣,但時間複雜度相同,都爲 O(n²)
3) 算時間複雜度的方 法:
 
用常數 1 代替運行時間中的全部加法常數  T(n)=n²+7n+6  => T(n)= n²+7n+1
修改後的運行次數函數中,只保留最高階項  T(n)= n²+7n+1 => T(n) = n²
去除最高階項的系 T(n) = => T(n) = n² => O(

常見的時間複雜度

1) 數階 O(1 )
2) 數階 O( log 2 n )
3) 性階 O(n )
4) 性對數階 O(n log 2 n )
5) 方階 O(n^2)
6) 方階 O(n^3)
7) k 次方階 O( n^k )
8) 數階 O(2^n )
常見的算法時間複雜度由小到大依次爲: Ο(1) Ο( log 2 n ) Ο( n) Ο( nlog 2 n ) Ο( n 2 ) Ο( n 3 ) Ο( n k ) Ο( 2 n ) ,隨 着問題規模 n 的不斷增大,上述時間複雜度不斷增大,算法的執行效率越
從圖中可見,咱們應該儘可 免使用 指數階的算法
 
 

1)數階O(1)

論代碼執行了多少行,只要是沒有循環等複雜結構,那這個代碼的時間複雜度就都是O(1)

上述代碼在執行的時候,它消耗的時候並不隨着某個變量的增加而增加,那麼不管這類代碼有多長,即便有幾萬幾十萬行,均可以用O(1)來表示它的時間複雜度。

2)對數階O(log2n)

while循環裏面,每次都將 i 乘以 2,乘完以後,i 距離 n 就愈來愈近了。假設循環x次以後,i 就大於 2 了,此時這個循環就退出了,也就是說 2 x 次方等於 n,那麼 x = log2n就是說當循環 log2n 次之後,這個代碼就結束了。所以這個代碼的時間複雜度爲:O(log2n O(log2n) 的這個2 時間上是根據代碼變化的,i = i * 3 ,則是 O(log3n) .

 

3)性階O(n)

說明:這段代碼,for循環裏面的代碼會執行n遍,所以它消耗的時間是隨着n的變化而變化的,所以這類代碼均可以用O(n)來表示它的時間複雜度

4)性對數階O(nlogN)

說明:線性對數階O(nlogN) 其實很是容易理解,將時間複雜度爲O(logn)的代碼循環N遍的話,那麼它的時間複雜度就是 n * O(logN),也就是了O(nlogN)

5)方階O(n²)

說明:平方階O(n²) 就更容易理解了,若是把 O(n) 的代碼再嵌套循環一遍,它的時間複雜度就是 O(n²)這段代碼其實就是嵌套了2n循環,它的時間複雜度就是 O(n*n),即  O(n²) 果將其中一層循環的n改爲m那它的時間複雜度就變成了 O(m*n)

6)方階O(n³)K次方階O(n^k)

考上面的O(n²) 去理解就行了,O(n³)至關於三層n循環,其它的相似

算法的時間複雜度

均時間複雜度和最壞時間複雜度

1) 均時間複雜度是指全部可能的輸入實例均以等機率出現的狀況下,該算法的運行時間
2) 壞狀況下的時間複雜度稱最壞時間複雜度。通常討論的時間複雜度均是最壞狀況下的時間複雜度。 這樣作的緣由是:最壞狀況下的時間複雜度是算法在任何輸入實例上運行時間的界限,這就保證了算法的運行時間不會比最壞狀況更長
3) 平均 時間 複雜度和 壞時間複雜度 否一致,和算法有關 ( 如圖 :)

算法的空間複雜度簡介

1) 似於時間複雜度的討論,一個算法的空間複雜度 (Space Complexity) 義爲該算法所耗費的存儲空間,它也是問題規模 n 的函數
2) 空間複雜度 (Space Complexity) 是對一個算法在運行過程當中臨時佔用存儲空間大小的量度 。有 的算法須要佔用的臨時工做單元數與解決問題的規模 n 有關,它隨着 n 的增大而增大,當 n 較大時,將佔用較多的存儲單元,例 如快 速排序和歸併排序算法就屬於這種情
3) 在作算法分析時, 主要討論的是時間複雜度 。從用戶使用體驗上看,更看重的程序執行的速度。一些緩存產品 ( redis , memcache ) 和算法 ( 基數排序 ) 本質就是用空間換時間 .
 
 

冒泡排序

冒泡排序(Bubble Sorting)的基本思想是:經過對待排序序列從前向從下標較小的元素開始),依次比較相鄰元素的若發現逆序則交換,使大的元素逐漸從移向後部,就象水底下的氣泡同樣逐漸向上冒。

/**
 * @author Sun.Mr
 * @create 2019-09-20 22:19
 */
public class Bubblesort {


    public static void main(String[] args) {
        int arr[] ={3,-2,9,10,7};

        int temp = 0;//臨時變量
        for (int i = 0; i <arr.length ; i++) {
            //若是前面的數比後面的數大,則交換
            for (int j = 0; j <arr.length-1-i ; j++) {
                if (arr[j] > arr[j+1]) {
                    temp=arr[j];
                    arr[j] =arr[j+1];
                    arr[j+1]=temp;
                }
            }
            System.out.println("第"+(i+1)+"趟排序後的數組");
            System.out.println(Arrays.toString(arr));
        }
    }
}

優化:由於排序的過程當中,各元素不斷接近本身的位置,若是一趟比較下來沒有進行過交換,就說明序列有序,所以要在排序過程當中設置一個標誌flag判斷元素是否進行過交換。從而減小沒必要要的比較

測試8000個數的冒泡排序的時間

排序80000個數,所需時間是9秒

選擇排序

擇式排序也屬於內部排序法,是從欲排序的數據中,按指定的規則選出某一元素,定交換位置後達到排序的目的

選擇排序思想:

選擇排序(select sorting)也是一種簡單的排序方法。它的基本思想是:第一次arr[0]~arr[n-1]中選取最小值,arr[0]交換,第二次arr[1]~arr[n-1]中選取最小值,arr[1]交換,第三次arr[2]~arr[n-1]中選取最小值,arr[2]交換,,第iarr[i-1]~arr[n-1]中選取最小值,arr[i-1]交換,…, n-1arr[n-2]~arr[n-1]中選取最小值,arr[n-2]交換,總共經過n-1次,獲得一個按排序碼從小到大排列的有序序列

選擇排序的思路圖解

相關文章
相關標籤/搜索