神奇少年的數據結構學習筆記一(算法)

目錄

1.初步接觸算法

2.算法的定義

3.算法的時間及空間複雜度


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.算法的定義

如今普遍認可的對於算法的定義是:

算法是解決特定問題求解步驟的描述,在計算機中表現爲指令的有限序列,並且每條指令表示一個或多個操作

算法的特性

  1. 輸入和輸出:對於大多數算法來說一般是需要輸入參數的,個別情況可以不要輸入參數,至少有一個或多個輸出;
  2. 有窮性:在執行完有限的步驟後,自動結束而不會無限循環,並且每個步驟在可接受的時間內完成;
  3. 確定性:每一步驟都有具體確定的含義,不會出現二義性。就是說相同的輸入只能有唯一的輸出結果;
  4. 可行性:每一步都是可行的。也就是說每一步都能通過執行有限的次數完成;

算法的設計要求

算法不是唯一的,同一個問題可能有多種不同的算法解決,所以談一下算法的設計要求,一個好的算法要滿足以下設計要求

  1. 正確性:指算法至少具有輸入輸出和加工無歧義性,能準確反映問題需求,得到問題正確答案;
  2. 可讀性:便於閱讀、理解和交流
  3. 健壯性:當輸入數據不合法時,算法也能做出相關處理,而不是產生異常或莫名其妙的結果;
  4. 時間效率高和儲存量低:應該是多個算法中 執行時間短和佔用存儲空間低的被使用

3.算法的時間及空間複雜度

   1.算法的時間複雜度  

    推導大O階方法 

  1. 用常數1取代運行時間中的所有加法常數
  2. 在修改後的運行次數函數中,只保留最高階項
  3. 如果最高項存在且不是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所佔存儲空間的函數

空間複雜度就是一個算法在運行過程中臨時佔用的存儲空間大小,換句話說就是被創建次數最多的變量,它被創建了多少次,那麼這個算法的空間複雜度就是多少。

歡迎大家評論交流或指出錯誤!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章