? ? ? 結構化的算法概況
結構化算法是由一些基本結構順序組成的,就是把一個大的功能的實現分隔為許多個小功能的實現。在基本結構之間不存在向前或向后的跳轉,流程的轉移只存在于一個基本的結構范圍內。一個非結構化的算法可以用一個等價的結構化算法代替,其功能不變。這樣的好處是可以將復雜問題簡單化,讓編程更容易,提高代碼維護和可讀性。
跟結構化算法比較起來,非結構化算法有以下缺點。
流程不受限制的隨意轉來轉去,使流程圖豪無規律。使人在閱讀的時候難以理解算法的邏輯。難以閱讀,也難以修改。從而使算法的可靠性和可維護性難以保證。
?
算法和結構化數據初識
數據結構定義:
我們如何把現實中大量而復雜的問題以特定的數據類型和特定的存儲結構保存到主存儲器(內存)中,以及在此基礎上為實現某個功能(如元素的CURD、排序等)而執行的相應操作,這個相應的操作也叫算法。
數據結構 = 元素 + 元素的關系 ;算法 = 對數據結構的操作;
算法:算法就是:解決問題的方法和步驟;
如計算機內存中棧和堆的區別,不懂數據結構的人可能會認為內存就是分兩大部分,一塊叫棧,一塊叫堆,顯然這是非常膚淺且不正確的結論。
實際上如果一塊內存是以壓棧出棧的方式分配的內存,那么這塊內存就叫棧內存,如果是以堆排序的方式分配的內存,那么這塊內存就叫堆內存,其最根本的區別還是其內存分配算法的不同。
例如,函數的調用方式也是通過壓棧出棧的方式來調用的,或者操作系統中多線程操作有隊列的概念,隊列用于保證多線程的操作順序,這也是數據結構里面的內容、或者計算機編譯原理里面有語法樹的概念,這實際上就是數據結構里面的樹,比如軟件工程、數據庫之類都有數據結構的影子。
在計算機系統中,CPU 可以直接操作內存,關于 CPU 對內存的操作與控制原理可以簡單理解如下圖:
地址線 : 確定操作哪個地址單元
控制線 : 控制該數據單元的讀寫屬性
數據線 : 傳輸 CPU 和內存之間的數據
什么叫結構體:結構體是用戶根據實際需要,自己定義的復合數據類型
指針:
指針就是地址,地址就是指針。
指針變量是存放內存單元地址的變量,它內部保存的值是對應的地址,地址就是內存單元的編號(如內存地址值:0xffc0)。
指針的本質是一個操作受限的非負整數
引用Quora上的回答:
I see it time and again in Google interviews or new-grad hires: The way data structures and algorithms—among the most important subjects in a proper computer science curriculum—are learnt is often insufficient. That‘s not to say students read the wrong books (see my recommendation below) or professors teach the wrong material, but how students ultimately come to understand the subject is lacking.(我多次在google面試或者畢業招聘的時候看到這樣的情形:學習數據結構和算法--CS課程里面幾乎最重要的課程--的方式很不科學!!到不是說大家用的書或者老師用的材料不對,而是說學生們對于這些課程本身的理解非常缺乏。)
The key to a solid foundation in data structures and algorithms is not an exhaustive survey of every conceivable data structure and its subforms, with memorization of each’s Big-O value and amortized cost. Such knowledge is great and impressive if you‘ve got it, but you will rarely need it. For better or worse, your career will likely never require you to implement a red-black tree node removal algorithm. But you ought be able—with complete ease!—to identify when a binary search tree is a useful solution to a problem, because you will often need that skill.(打好數據結構和算法基礎的關鍵并不在于對于所有數據結構的細致的了解,不是記住每一個大O值或者攤余成本。. )。
如果這些知識你都掌握了,當然很棒并且可以給人留下很深的印象,但是你基本上用不著啊!
你的職業生涯中或許永遠都不會要求你實現一個紅黑樹刪除節點的算法。但是!你必須有能力而且手起刀落輕輕松松的識別出什么時候使用二叉樹更簡單更有效, 因為你十分需要這樣的技巧。)
So stop trying to memorize everything. Instead, start with the basics and learn to do two things:
Visualize the data structure. Intuitively understand what the data structurelooks like, what it feels like to use it, and how it is structured both in the abstract and physically in your computer’s memory. This is the single most important thing you can do, and it is useful from the simplest queues and stacks up through the most complicated self-balancing tree. Draw it, visualize it in your head, whatever you need to do: Understand the structure intuitively.
Learn when and how to use different data structures and their algorithms in your own code. This is harder as a student, as the problem assignments you‘ll work through just won’t impart this knowledge. That‘s fine. Realize you won’t master data structures until you are working on a real-world problem and discover that a hash is the solution to your performance woes. But even as a student you should focus on learning not the minutia details but the practicalities: When do you want a hash? When do you want a tree? When is a min-heap the right solution?
(所以,不要試圖記住所有的東西。而是從基礎開始,做兩件事:
第一件事。 把數據結構圖形化,視覺化。(突然想起來我高中競賽老師說的一句話:數形結合千般好,一旦不做萬事休啊! 就是要畫圖! )在直覺上感受一個數據結構是什么樣子的。使用它是什么感覺,抽象上和具體實現上是什么樣子的。這就是最重要的事情。并且無論是對于簡單的隊列,棧還是天殺的平衡樹都很重要而且有效。把數據結構畫出來,在你的腦袋瓜里面就能想象出來,總之,你需要做的就是,直觀的去了解這些數據結構。
第二件事。學習什么時候用什么樣的數據結構和算法。對于學生來說這很難,而且你要做作業的時候老師也沒告訴你們這該怎么辦。不過沒關系。 你要認識到當你真正處理到現實問題的時候或許你才能掌握某些數據結構,比如哈希表。但是即使是個學生,你也應該知道數據結構的實用性:什么時候你需要個哈希表,什么時候你需要個樹,什么時候你需要個堆? 而不是一開始就陷入到追求細節中去。)
One of the questions I ask in Google engineering interviews has a binary search tree as a potential solution (among others)。 Good candidates can arrive at the binary search tree as the right path in a few minutes, and then take 10-15 minutes working through the rest of the problem and the other roadblocks I toss out. But occasionally I get a candidate who intuitively understands trees and can visualize the problem I‘m presenting. They might stumble on the exact algorithmic complexity of some operation, but they can respond to roadblocks without pause because they can visualize the tree. They get it.
(我在google面試的時候,我經常會問一個可以由二叉樹搜索解決的問題。 好的應聘者可以幾分鐘內就可以想到用二叉樹來解決,而且對于我的其他問題也差不多10-15分鐘就可以解決。當然,偶爾會有一個應聘者,他能直觀的認識樹這種結構,而且可以把我的問題形象化,圖形化的描述出來。當然他或許對于某些操作的時間復雜度不甚了解,但是對于問題他卻可以立馬回應,因為他們腦袋里就有這樣的樹結構啊,所以他也能拿到工作啊。)
As for a book, there is but one: Introduction to Algorithms by Cormen, Leiserson, Rivest, and Stein, otherwise known as CLRS.
至于書,只推薦一本--- 《算法導論》
If you want another text, perhaps one with more examples in a specific language, I recommend Robert Sedgewick’s Algorithms in C++ orAlgorithms in Java, as appropriate. I prefer CLRS as a text, but you might find these a better teaching aid.
對于某個數據結構,幾步:
1、理解該數據結構的基本概念(定義、實現)
2、嘗試理解這個數據結構的意義(為什么它會被發明)
3、用這種數據結構解決一些對應的例題(書本上的習題、Online Judge上的水題)
4、嘗試用這個數據結構解決一些以往你用別的數據結構解決的問題,能否解決,為什么。
5、再次嘗試理解這個數據結構的意義
6、嘗試改變這個數據結構以應對各種現實的問題(Online Judge的好題)
7、學好數學,別數都不會數。
初級篇
記住都有哪些算法,解決什么問題
去試圖解決實際的問題,自然會碰到之前算法解決的問題,使用這些算法
中極篇
先完成初級篇
記住算法的具體解決辦法
實際的問題 如果有與標準算法相似但是不完全一樣的,仔細分析差別,修改原有算法
高級篇
先完成中極篇
分析一下算法的解決辦法是如何才能想到,最核心和最精妙的地方在哪兒
實際的問題如果與標準算法都不太象,仔細想想這個問題的本質,借鑒經典算法精妙之處,自己設計自己要用的算法
骨灰篇
先完成高級篇
忘掉所有算法
解決實際問題
評論
查看更多