資料結構和演算法概述
阿新 • • 發佈:2020-12-04
1 資料結構
1.1 什麼是資料結構?
- 資料結構是一門研究非數值計算的程式設計問題中的操作物件,以及它們之間的關係和操作等相關問題的學科。
- 簡而言之,資料結構就是把資料元素按照一定的關係組織起來的集合,用來組織和儲存資料。
1.2 資料結構的分類
1.2.1 概述
- 傳統上,我們可以把資料結構分為邏輯結構和物理結構兩大類。
1.2.2 邏輯結構分類
- 邏輯結構是從具體問題中抽象出來的模型,是抽象意義上的結構,按照物件中資料元素之間的相互關係分類,也是我們需要關注和討論的問題。
- 1️⃣集合結構:集合結構中資料元素除了屬於同一個集合外,它們之間沒有任何其他的關係。
- 2️⃣線性結構:線性結構中的資料元素之間存在一對一的關係。
- 3️⃣樹形結構:樹形結構中的資料元素之間存在一對多的關係。
- 4️⃣圖形結構:圖形結構的資料元素是多對多的關係。
1.2.3 物理結構分類
-
邏輯結構是在計算機中真正的表達方式稱為物理結構,也可以叫做儲存結構。常見的物理解耦股有順序儲存結構、鏈式儲存結構。
-
1️⃣順序儲存結構:
- 把資料元素放到地址連續的儲存單元裡面,其資料間的邏輯關係和物理關係是一致的,比如我們常用的陣列就是順序儲存結構。
- 順序儲存結構存在一定的弊端,就像生活中排隊時,有人插隊,也有人有特殊情況突然離開,這時候整個結構就處於變化中,此時就需要使用鏈式儲存結構了。
-
2️⃣鏈式儲存結構:
- 把資料元素放在任意的儲存單元裡面,這組儲存單元可以是連續的,也可以是不連續的。此時,資料元素之間並不能反映元素間的邏輯關係,因此在鏈式儲存結構中引進了一個指標儲存資料元素的地址,這樣通過地址就可以找到相關聯資料元素的位置。
2 演算法
1.1 概述
- 演算法是指解題方案的準確而完整的描述,是一系列解決問題的清晰指令,演算法代表著用系統的方法解決問題的策略機制。也就是說,能夠對一定規範的輸入,在有限的時間內獲得所要求的結果。
- 簡而言之,演算法就是根據一定的條件,對一些資料進行計算,得到需要的結果。
1.2 演算法初體驗
-
在生活中,我們如果遇到某個問題,常常解決方案不是唯一的。
-
例如,從西安到北京,如何去?會有不同的解決方案,我們可以坐飛機、可以坐火車、可以坐汽車,甚至可以步行,不同的解決方案帶來的時間成本和經濟成本是不一樣的,比如坐飛機用的時間最少,但是費用最高;步行費用最低,但是時間最長。
-
例如,在北京二環內買一套四合院,如何付款?也會有不同的解決方案,可以一次性現金付清,也可以通過銀行做按揭。這兩種方案帶來的成本也是不一樣的,一次性付清,雖然當時給的錢多,壓力大,但是沒有利息;按揭雖然當時出的錢少,壓力比較小,但是會有利息,而且30年的總利息幾乎是貸款額度的一倍,需要多付不少錢。
-
在程式中,我們也可以用不同的演算法解決相同的問題,而不同的演算法的成本是不相同的。總體上,一個優秀的演算法追求以下兩個目標:
- 1️⃣花最少的時間完成需求。
- 2️⃣佔用最少的記憶體空間完成需求。
-
下面我們用一些實際的案例體驗一些演算法。
-
案例1:計算1到100的和。
package com.sunxiaping;
/**
* ①定義兩個整型變數
* ②執行100次加法運算
* ③列印結果到控制檯
*
* @author 許大仙
* @version 1.0
* @since 2020-12-04 11:19
*/
public class Init {
public static void main(String[] args) {
int sum = 0;
int n = 100;
for (int i = 0; i <= n; i++) {
sum += i;
}
System.out.println("sum = " + sum);
}
}
package com.sunxiaping;
/**
* ①定義兩個整型變數
* ②執行一次加法運算,一次乘法運算,一次除法運算,總共3次運算
* ③列印結果到控制檯
*
* @author 許大仙
* @version 1.0
* @since 2020-12-04 11:19
*/
public class Init {
public static void main(String[] args) {
int sum = 0;
int n = 100;
sum = (n + 1) * n / 2;
System.out.println("sum = " + sum);
}
}
第二種演算法完成需求,花費的時間更少一些。
- 案例2:計算10的階乘
package com.sunxiaping;
/**
* 使用遞迴完成需求,fun方法會執行10次,並且第一次執行未完成,呼叫第二次執行,依次內推,最多的時候,需要在棧記憶體開闢10塊記憶體分別執行10個fun方法
*
* @author 許大仙
* @version 1.0
* @since 2020-12-04 11:19
*/
public class Init {
public static void main(String[] args) {
//測試:計算10的階乘
long fun = fun(10);
System.out.println("fun = " + fun);
}
/**
* 計算n的階乘
*
* @param n
* @return
*/
public static long fun(long n) {
if (n == 1) {
return 1;
}
return n * fun(n - 1);
}
}
package com.sunxiaping;
/**
* 使用for迴圈完成需求,fun2方法只會執行一次,最終,只需要在棧記憶體開闢一塊記憶體執行fun2方法即可
*
* @author 許大仙
* @version 1.0
* @since 2020-12-04 11:19
*/
public class Init {
public static void main(String[] args) {
//測試:計算10的階乘
long fun = fun2(10);
System.out.println("fun = " + fun);
}
/**
* 計算n的階乘
*
* @param n
* @return
*/
public static long fun2(long n) {
long result = 1;
for (long i = 1; i <= n; i++) {
result *= i;
}
return result;
}
}
第二種演算法完成需求,佔用的記憶體空間更小。