1. 程式人生 > 實用技巧 >資料結構與演算法入門基礎

資料結構與演算法入門基礎

1、為什麼要學習資料結構與演算法呢?

思考這樣一道題目:

判斷一個數是否是2的N次方? 如 2 4 8 16是 6 10 不是

思路: 看這個數能不能拆成N個2相乘

/**
* 判斷一個數是否是2的N次方
* @param num
* @return
*/
public static boolean isTwoToThePowerOfN(int num){
while(num%2==0){
num = num/2;
}
if(num==1){
return true;
}
return false;
}

但這個不是最優解,我們看到2的時候,要有資料進位制的感念,也就是二進位制(計算機基礎知識),先看下這幾個數在計算機儲存的形式

2:10

4:100

8:1000

16:10000

再看一組數

1:01

2:10 --》 10 & 01 == 0

3:011

4:100 --》 100 & 001 == 0

7:0111

8:1000 --》 1000& 0111 == 0

15:01111

16:10000 --》 10000 & 01111 == 0

大家發現規律沒有,通過按位與運算我們可以優化成這樣的程式碼

/**
* 判斷一個數是否是2的N次方 按位與運算
* @param num
* @return
*/
public static boolean isTwoToThePowerForAndByBit(int num){
if((num & (num-1)) == 0){
return true;
}
return false;
}

所以有了資料結構與演算法思想,就可以想出更高效的解決問題的思路。

回答問題1

1、不想一輩子做crud工程師

2、程式設計師往架構師發展,需要掌握能寫出架構級、框架級、開源級程式碼的能力

3、大公司如bat面試都會問

4、提升自己的能力,不被行業淘汰

什麼是資料結構?什麼是演算法?

資料結構就是一個能組合到一起的集合物件,如陣列 連結串列 佇列等

演算法就是解決問題

演算法的特徵:

有窮性 確定性 可行性 有輸入輸出

設計的原則:

正確性、可讀性、健壯性(少bug) :寫出來的程式碼bug很少,而且系統比較穩定

高效率低儲存

評價演算法的兩個重要的指標:

時間複雜度:執行一個程式所花費的時間。O()

空間複雜度:執行程式所需要的的記憶體。OOM

一、時間複雜度

1、時間複雜度的計算的意義?

介面、功能測試,壓測,冒煙,需要測試環境依賴,流程很長,如果資料或者配置沒對會導致測試有問題,所以我們應該根據自己的程式碼自己去用程式碼分析,也就是時間複雜度

2、時間複雜度的表示方法:大O表示法 O(n) O(logn) O(nlogn) O(1) ...... O(n的表示式)

3、時間複雜度如何分析

1)尋找for while 迴圈,而且是迴圈最大的

2)同級迴圈怎麼算?

4、幾種常見的時間複雜度分析:時間複雜度往往是計算比較大的,而且是不確定的數,如果已經確定了,那就不用計算了,也就是我們所說的常量

1)常數 O(1) 1表示常數,所有能確定的數字,我們都用O(1)表示 O(100000)=》O(1)

int a=1

for(int i=0;i<3;i++){

  a = a+1;

}

2)對數 O(logn) 二分查詢

int n = xxx;

int i = 1;

while(i<=n){

  i=i*2

}

i的數是:2 4 8 16 32 =》2^0 2^1 2^2 2^3 ......2^n

2^x=n => 求出x= log2n 計算機忽略常數 => logn

3)線性 O(n)

int n = xxx;

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

  a=a+1;

}

4)線性對數 O(nlogn)

int n = xxx;

int i = 1;

for(int j = 0;j<n;j++){

  while(i<=n){

    i=i*2

  }

}

這個是 nlogn

5)平方O(n^2) 氣泡排序

for(int j = 0;j<n;j++){

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

    a=a+1;

  }

}

氣泡排序

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

  for(int j= i; j < n; j++){

    a=a+1;

  }

}

n*(n+1)/2 ==> 忽略常數 ==》 n^2 有加減法取最大的

6)N平方 O(n^n)

總結:分析程式,首先去找執行次數最多的地方

1、有迴圈的地方

2、有網路請求(RPC,遠端呼叫,分散式,資料庫請求)

學了時間複雜度後,我們的目標是要把程式碼寫到最優,效率最高:

O(1)>O(logn)>O(n)>O(nlogn)>O(n^2)>O(n^x) 優化的方案是往O(1)的方向靠近

O(1)>O(logn)>O(n)>O(nlogn) 效果都是很好的

二、空間複雜度

1、空間複雜度分析的意義: 找花了記憶體的地方,也就是資料

2、如何找出空間複雜度:開了空間的地方,如 陣列 連結串列 快取物件 遞迴

某老師推薦的書:

資料結構: 1、嚴蔚敏版 資料結構與演算法(大學時期學過,全部還給老師了) 2、大話資料結構

演算法:1、基礎:演算法競賽入門經典

練習網站:

力扣 https://leetcode-cn.com/leetbook/

北京大學 http://poj.org/ 對演算法特別熱愛的可以關注下

杭州電子科技大學 http://acm.hdu.edu.cn/ 對演算法特別熱愛的可以關注下