在理解演算法的時間複雜度上,理論很重要,由於以下幾個原因,實際因素在真正的效能表現上也扮演著很重要的角色。
乙個演算法的分析一般認為所有的步驟都花費相同的時間,即使現實並非如此。例如,創造和摧毀乙個新的物件可能比把陣列中的乙個整數值移動到另一位置花費更多的時間。在這種情況下,乙個使用陣列的演算法優於乙個使用許多物件的演算法,即使第二個演算法在大o符號中表現更好。
許多程式設計環境也提供了訪問作業系統的功能。這些功能遠比基礎的演算法技巧高效。例如,插入排序演算法的一部分要求是把陣列的某些元素向下移動乙個位置,以便能在它們之前插入乙個新的元素。這是乙個相當慢的程序,很大程度上導致了演算法的時間複雜度為o(n2)。然而,許多程式可以使用現有的函式(比如.net中的rtlmovememory和windows c++中的movememory)一次同時移動許多塊儲存內容。這些函式不是在陣列中乙個乙個移動元素,而是一次移動許多元素,乙個程式可以呼叫這些函式一次移動陣列中一系列值,使程式更快。
乙個演算法具有一定的理論漸近效能,並不意味著不能使用程式設計環境提供的工具來改善效能。一些程式設計環境也能提供一些工具,可以執行與書中演算法相同的任務。例如,許多庫包含排序例程。它們在排列陣列上表現出色。c#和vb所使用的microsoft抯 .net framework包含了乙個array.sort方法。至少是一般情況下,幾乎不可能用你自己的**打敗它。對於特定的問題,如果有關於資料的額外資訊,仍然能夠打敗array.sort的效能。(更多的資訊請閱讀6.3.1節中的計數排序。)
專用庫也可以幫助解決某些特定問題。例如,可以使用乙個網路分析庫而不是編寫自己的網路工具。同樣的,資料庫工具也可以節省很多建立樹和整理資料的時間。建立自己的平衡樹,可能會獲得更好的效能,但是使用資料庫使得工作量更少。
如果你的程式設計工具包含著可以執行這些演算法中某乙個任務的功能,只管用它們。可能會獲得比自己編寫的演算法更好的效能,也一定能減少一些除錯工作。
最後,最好的演算法並不總是在解決大規模的問題中執行最快的那個。如果排列大量的數字,快速排序通常會提供良好的效能。但是如果只排列三個數字,一系列簡單的if語句可能會有更好的效能並且簡單得多。即使快速排序的效能的確更好,程式一毫秒完成排序還是二毫秒完成排序真的重要嗎?如果需要多次執行排序,否則最好使用簡單的、更加容易除錯和維護的演算法而不是使用複雜的演算法去節約一毫秒。
如果使用庫,比如前面段落中描述的庫,則可能不需要自己把所有這些敲出來,但是理解這些演算法如何工作仍然有用。如果理解了這些演算法,即使你沒有真正編寫它們。也可以更好地利用它們來完成工作,例如,如果知道了關係型資料庫一般使用b樹(或者類似的樹)來儲存它們的索引,這樣將會更好地理解預分配和填充因子的重要性。如果理解了快速排序,這樣就會知道為什麼一些人認為.net 框架中的array.sort方法在密碼的角度上是不安全的(這在6.2.2節中的「使用快速排序」部分討論)。
理解演算法也需要把它們應用到其他狀況中。某個具體應用中可能不需要歸併排序,但是可能會使用它的分治思想來解決多處理器上的其他問題。
AcWing演算法基礎1 5
字首和與差分 兩個內容都比較少,就放一起寫了 設陣列 a 的前 n 項為a1 a2 a3 an 字首和陣列就是每一項是a陣列的前i項和,比如字首和陣列res,res 1 a 1 res 2 a 1 a 2 res n a 1 a 2 a n 字首和可以在o 1 的時間內計算一段區間內的累加和,比如區...
演算法實際運用
我們在linux中用select實現多路復用中有幾個巨集 fd set fd clr fd zero在這裡充分利用到了集合的概念和演算法 因一項工作而卡住需等待這項工作時,導致別的工作不能完全進行 這樣浪費資源和時間 怎麼處理呢 這裡有幾種解決的方法 其中一種就是每隔一段時間進行迴圈檢測看這項工作是...
雙因素演算法存疑
可以參考阮一峰老師的這篇文章,這裡主要對阮老師提供的演算法存疑 tc floor unixtime now 30 你是看懂了,但你沒動手驗證過,這個演算法沒法保證在30s內是相同的 舉個例子 1510279844 1510279845 這2個時間戳只差了1s,但兩者除以30四捨五入後並不相等,望修正...