因爲是非科班培訓出來的,所以一直想要學習這些基礎的知識,最近入手了一本《大話數據結構》
看評論應該很適合初入門,不是太懂的,所以這個專欄分享一些我學習數據結構的筆記,有什麼不對的地方,歡迎大家指出
目錄
1.初步接觸算法
正常情況下,要算1~100相加的值,一般程序員第一想法都是 for循環相加算出結果,這也是一種算法
但是說到 高斯求和算法 可能不少的程序員都知道這個算法,但是可能都是記住了但是沒有拿出來實用
/// <summary>
/// 1~100循環算法
/// </summary>
/// <returns></returns>
public int GetSum()
{
int sum = 0, n = 100;
for (int i = 0; i < n; i++)
{
sum = sum + i;
}
return sum;
}
/// <summary>
/// 高斯求和算法
/// </summary>
/// <returns></returns>
public int GaussSummation()
{
int sum = 0, n = 100;
sum = (1 + n) * n / 2;
return sum;
}
循環算法的話,求多少的和就得循環多少次,而高斯求和算法無論相加到多少都只需要執行一次,所以算法的質量是很重要的
2.算法的定義
如今普遍認可的對於算法的定義是:
算法是解決特定問題求解步驟的描述,在計算機中表現爲指令的有限序列,並且每條指令表示一個或多個操作
算法的特性
- 輸入和輸出:對於大多數算法來說一般是需要輸入參數的,個別情況可以不要輸入參數,至少有一個或多個輸出;
- 有窮性:在執行完有限的步驟後,自動結束而不會無限循環,並且每個步驟在可接受的時間內完成;
- 確定性:每一步驟都有具體確定的含義,不會出現二義性。就是說相同的輸入只能有唯一的輸出結果;
- 可行性:每一步都是可行的。也就是說每一步都能通過執行有限的次數完成;
算法的設計要求
算法不是唯一的,同一個問題可能有多種不同的算法解決,所以談一下算法的設計要求,一個好的算法要滿足以下設計要求
- 正確性:指算法至少具有輸入輸出和加工無歧義性,能準確反映問題需求,得到問題正確答案;
- 可讀性:便於閱讀、理解和交流
- 健壯性:當輸入數據不合法時,算法也能做出相關處理,而不是產生異常或莫名其妙的結果;
- 時間效率高和儲存量低:應該是多個算法中 執行時間短和佔用存儲空間低的被使用
3.算法的時間及空間複雜度
1.算法的時間複雜度
推導大O階方法
- 用常數1取代運行時間中的所有加法常數
- 在修改後的運行次數函數中,只保留最高階項
- 如果最高項存在且不是1,去除這個項相乘的常數,得到的就是大O階
//用O()表示時間複雜度的記法 稱爲大O記法
//------------------------------------常數階 O(1)
int sum = 0, n = 100; //執行一次
sum = (1 + n) * n / 2; //執行一次
Console.WriteLine(sum); //執行一次
//注意:保留最高階項,所以這個不是 O(3) 而是 O(1),單純分支結構(不包含在循環結構中),其時間複雜度也是O(1)
//------------------------------------線性階 O(n)
for (int i = 0; i < n; i++)
{
sum = sum + i; //執行n次
} //循環內執行n次,所以是O(n)
//------------------------------------對數階 O(logn) 執行n的1/2次
int count = 1;
while (count < n)
{
count = count * 2;
} //由於每次count乘以2以後,就相當於有多少個2相乘後大於n則退出循環,由於2的x次方=n 所以時間複雜度爲 O(logn)
//------------------------------------平方階 O(n²) 執行n的平方次
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; i++)
{
//執行n*n次
}
} //循環內執行n²次,所以是O(n²)
由上述代碼可以看出 循環體的時間複雜程度等於循環體的複雜度乘以改循環的運行次數
執行函數次數 | 階 | 非正式術語 |
---|---|---|
1 | O(1) | 常數階 |
2n+3 | O(n) | 線性階 |
3n² +2n+1 | O(n² ) | 平方階 |
5log2(n)+20 | O(logn) | 對數階 |
2n+3nlog2(n)+19 | O(nlogn) | nlogn階 |
6n³+2n³+3n+4 | O(n³) | 立方階 |
2ⁿ | O(2ⁿ) |
指數階 |
常用的時間複雜度所耗費的時間從小到大依次是:
O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2ⁿ)<O(n!)<O(nⁿ)
一般在O(n²)平方階之後的時間複雜度 ,會由於n值導致噩夢般的運行時間,所以一般不討論
2.算法的空間複雜度
可以在空間和時間之間進行平衡,空間換取時間
公式爲 S(n)=O(f(n)) 其中n爲問題的規模,f(n)爲語句關於n所佔存儲空間的函數