1. 程式人生 > >Java資料結構和演算法(一):簡介

Java資料結構和演算法(一):簡介

  本系列部落格我們將學習資料結構和演算法,為什麼要學習資料結構和演算法,這裡我舉個簡單的例子。

  程式設計好比是一輛汽車,而資料結構和演算法是汽車內部的變速箱。一個開車的人不懂變速箱的原理也是能開車的,同理一個不懂資料結構和演算法的人也能程式設計。但是如果一個開車的人懂變速箱的原理,比如降低速度來獲得更大的牽引力,或者通過降低牽引力來獲得更快的行駛速度。那麼爬坡時使用1檔,便可以獲得更大的牽引力;下坡時便使用低檔限制車的行駛速度。回到程式設計而言,比如將一個班級的學生名字要臨時儲存在記憶體中,你會選擇什麼資料結構來儲存,陣列還是ArrayList,或者HashSet,或者別的資料結構。如果不懂資料結構的,可能隨便選擇一個容器來儲存,也能完成所有的功能,但是後期如果隨著學生資料量的增多,隨便選擇的資料結構肯定會存在效能問題,而一個懂資料結構和演算法的人,在實際程式設計中會選擇適當的資料結構來解決相應的問題,會極大的提高程式的效能。

1、資料結構

  資料結構是計算機儲存、組織資料的方式,指相互之間存在一種或多種特定關係的資料元素的集合。

  通常情況下,精心選擇的資料結構可以帶來更高的執行或者儲存效率。資料結構往往同高效的檢索演算法和索引技術有關。

  一、資料結構的基本功能

  ①、如何插入一條新的資料項

  ②、如何尋找某一特定的資料項

  ③、如何刪除某一特定的資料項

  ④、如何迭代的訪問各個資料項,以便進行顯示或其他操作

  二、常用的資料結構

   

 

  這幾種結構優缺點如下:先有個大概印象,後面會詳細講解!!!

  

2、演算法

  演算法簡單來說就是解決問題的步驟。

  在Java中,演算法通常都是由類的方法來實現的。前面的資料結構,比如連結串列為啥插入、刪除快,而查詢慢,平衡的二叉樹插入、刪除、查詢都快,這都是實現這些資料結構的演算法所造成的。後面我們講的各種排序實現也是演算法範疇的重要領域。

  一、演算法的五個特徵

  ①、有窮性:對於任意一組合法輸入值,在執行又窮步驟之後一定能結束,即:演算法中的每個步驟都能在有限時間內完成。

  ②、確定性:在每種情況下所應執行的操作,在演算法中都有確切的規定,使演算法的執行者或閱讀者都能明確其含義及如何執行。並且在任何條件下,演算法都只有一條執行路徑。

  ③、可行性:演算法中的所有操作都必須足夠基本,都可以通過已經實現的基本操作運算有限次實現之。

  ④、有輸入:作為演算法加工物件的量值,通常體現在演算法當中的一組變數。有些輸入量需要在演算法執行的過程中輸入,而有的演算法表面上可以沒有輸入,實際上已被嵌入演算法之中。

  ⑤、有輸出:它是一組與“輸入”有確定關係的量值,是演算法進行資訊加工後得到的結果,這種確定關係即為演算法功能。

  二、演算法的設計原則

  ①、正確性:首先,演算法應當滿足以特定的“規則說明”方式給出的需求。其次,對演算法是否“正確”的理解可以有以下四個層次:

        一、程式語法錯誤。

        二、程式對於幾組輸入資料能夠得出滿足需要的結果。

        三、程式對於精心選擇的、典型、苛刻切帶有刁難性的幾組輸入資料能夠得出滿足要求的結果。

        四、程式對於一切合法的輸入資料都能得到滿足要求的結果。

        PS:通常以第 三 層意義的正確性作為衡量一個演算法是否合格的標準。

  ②、可讀性:演算法為了人的閱讀與交流,其次才是計算機執行。因此演算法應該易於人的理解;另一方面,晦澀難懂的程式易於隱藏較多的錯誤而難以除錯。

  ③、健壯性:當輸入的資料非法時,演算法應當恰當的做出反應或進行相應處理,而不是產生莫名其妙的輸出結果。並且,處理出錯的方法不應是中斷程式執行,而是應當返回一個表示錯誤或錯誤性質的值,以便在更高的抽象層次上進行處理。

  ④、高效率與低儲存量需求:通常演算法效率值得是演算法執行時間;儲存量是指演算法執行過程中所需要的最大儲存空間,兩者都與問題的規模有關。

  前面三點 正確性,可讀性和健壯性相信都好理解。對於第四點演算法的執行效率和儲存量,我們知道比較演算法的時候,可能會說“A演算法比B演算法快兩倍”之類的話,但實際上這種說法沒有任何意義。因為當資料項個數發生變化時,A演算法和B演算法的效率比例也會發生變化,比如資料項增加了50%,可能A演算法比B演算法快三倍,但是如果資料項減少了50%,可能A演算法和B演算法速度一樣。所以描述演算法的速度必須要和資料項的個數聯絡起來。也就是“大O”表示法,它是一種演算法複雜度的相對錶示方式,這裡我簡單介紹一下,後面會根據具體的演算法來描述。

  相對(relative):你只能比較相同的事物。你不能把一個做算數乘法的演算法和排序整數列表的演算法進行比較。但是,比較2個演算法所做的算術操作(一個做乘法,一個做加法)將會告訴你一些有意義的東西;

  表示(representation):大O(用它最簡單的形式)把演算法間的比較簡化為了一個單一變數。這個變數的選擇基於觀察或假設。例如,排序演算法之間的對比通常是基於比較操作(比較2個結點來決定這2個結點的相對順序)。這裡面就假設了比較操作的計算開銷很大。但是,如果比較操作的計算開銷不大,而交換操作的計算開銷很大,又會怎麼樣呢?這就改變了先前的比較方式;

  複雜度(complexity):如果排序10,000個元素花費了我1秒,那麼排序1百萬個元素會花多少時間?在這個例子裡,複雜度就是相對其他東西的度量結果。

  然後我們在說說演算法的儲存量,包括:

  程式本身所佔空間;

  輸入資料所佔空間;

  輔助變數所佔空間;

  一個演算法的效率越高越好,而儲存量是越低越好。

3、總結

  本篇文章我們簡單的介紹了資料結構和演算法的概念,演算法是解決問題的步驟,而資料結構的實現離不開演算法,可能理解起來比較模糊,不用擔心,後面我們會在具體的資料結構和演算法實現過程中詳細講解。