數據結構
數據結構是計算機存儲、組織數據的方式。程序員
算法效率
算法效率是指算法執行的時間,算法執行時間需經過依據該 算法編制的程序在計算機上運行時所消耗的時間來度量。算法
哈希表(Hash table,也叫散列表),是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,它經過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫作散列函數,存放記錄的數組叫作散列表。
記錄的存儲位置=f(關鍵字)
這裏的對應關係f稱爲散列函數,又稱爲哈希(Hash函數),採用散列技術將記錄存儲在一塊連續的存儲空間中,這塊連續存儲空間稱爲散列表或哈希表(Hash table)。編程
數組的特色是:尋址容易,插入和刪除困難;數組
而鏈表的特色是:尋址困難,插入和刪除容易。數據結構
那麼咱們能不能綜合二者的特性,作出一種尋址容易,插入刪除也容易的數據結構?答案是確定的,這就是咱們要提起的哈希表,哈希表有多種不一樣的實現方法,我接下來解釋的是最經常使用的一種方法——拉鍊法,咱們能夠理解爲「鏈表的數組」,如圖:
函數
散列表的查找步驟
當存儲記錄時,經過散列函數計算出記錄的散列地址
當查找記錄時,咱們經過一樣的是散列函數計算記錄的散列地址,並按此散列地址訪問該記錄性能
優缺點
優勢:不論哈希表中有多少數據,查找、插入、刪除(有時包括刪除)只須要接近常量的時間即0(1)的時間級。實際上,這隻須要幾條機器指令。
哈希表運算得很是快,在計算機程序中,若是須要在一秒種內查找上千條記錄一般使用哈希表(例如拼寫檢查器)哈希表的速度明顯比樹快,樹的操做一般須要O(N)的時間級。哈希表不只速度快,編程實現也相對容易。
若是不須要有序遍歷數據,而且能夠提早預測數據量的大小。那麼哈希表在速度和易用性方面是無與倫比的。
缺點:它是基於數組的,數組建立後難於擴展,某些哈希表被基本填滿時,性能降低得很是嚴重,因此程序員必需要清楚表中將要存儲多少數據(或者準備好按期地把數據轉移到更大的哈希表中,這是個費時的過程)。學習
問題解決:軟件工程包含程序設計,已經不僅僅是侷限於編寫代碼,而是應該考慮程序的簡潔性,實用性。簡單來講,軟件工程考慮的要更加全面具體。測試
問題解決:一個是時間複雜度,一個是漸近時間複雜度。前者是某個算法的時間耗費,它是該算法所求解問題規模n的函數,然後者是指當問題規模趨向無窮大時,該算法時間複雜度的數量級。
當咱們評價一個算法的時間性能時,主要標準就是算法的漸近時間複雜度,所以,在算法分析時,每每對二者不予區分,常常是將漸近時間複雜度T(n)=O(f(n))簡稱爲時間複雜度
其中的f(n)通常是算法中頻度最大的語句頻度。語句頻度是一個算法中的語句執行次數。
沒有循環的一段程序的複雜度是常數,一層循環的複雜度是O(n),兩層循環的複雜度是O(n^2)優化
問題解決:
語句頻度和數據結構中時間複雜度的區別。
1)時間頻度一個算法執行所耗費的時間,從理論上是不能算出來的,必須上機運行測試才能知道。但咱們不可能也沒有必要對每一個算法都上機測試,只需知道哪一個算法花費的時間多,哪一個算法花費的時間少就能夠了。而且一個算法花費的時間與算法中語句的執行次數成正比例,哪一個算法中語句執行次數多,它花費時間就多。一個算法中的語句執行次數稱爲語句頻度或時間頻度。記爲T(n)。
(2)時間複雜度在剛纔提到的時間頻度中,n稱爲問題的規模,當n不斷變化時,時間頻度T(n)也會不斷變化。但有時咱們想知道它變化時呈現什麼規律。爲此,咱們引入時間複雜度概念。通常狀況下,算法中基本操做重複執行的次數是問題規模n的某個函數,用T(n)表示,如有某個輔助函數f(n),使得當n趨近於無窮大時,T(n)/f(n)的極限值爲不等於零的常數,則稱f(n)是T(n)的同數量級函數。記做T(n)=O(f(n)),稱O(f(n)) 爲算法的漸進時間複雜度,簡稱時間複雜度。在各類不一樣算法中,若算法中語句執行次數爲一個常數,則時間複雜度爲O(1),另外,在時間頻度不相同時,時間複雜度有可能相同,如T(n)=n^2+3n+4與T(n)=4n^2+2n-1它們的頻度不一樣,但時間複雜度相同,都爲O(n2)。
按數量級遞增排列,常見的時間複雜度有:常數階O(1),對數階O(log2n),線性階O(n),線性對數階O(nlog2n),平方階O(n2),立方階O(n3),...,k次方階O(nk),指數階O(2n)。隨着問題規模n的不斷增大,上述時間複雜度不斷增大,算法的執行效率越低。
複雜度關係
c < log2N < n < n * Log2N < n^2 < n^3 < 2^n < 3^n < n!
問題解決:答案是0(1),
由於是在表尾插入的,順序表讀取表尾元素是個常量級操做,插入操做無需移動所以也是個常量級操做。
博客內容詳細,對於一些知識點有本身的理解和簡單分析。不過在複雜度方面博客附圖中已經顯示了,我認爲2的n次方比n的3次方要大。但願能夠探討一下。
for(int count = 0 ; count < n ; count++) for(int count2 = 0 ; count2 < n ; count2 = count2 + 2) { System.out.println(count,count2); } }
由題,內層循環是n/2,外層循環是n,因此增加函數f(n) = n^2 /2,因此階次是O(n^2)。
for(int count = 0 ; count < n ; count++) for(int count2 = 0 ; count2 < n ; count2 = count2 * 2) { System.out.println(count,count2); } }
由題,內層循環是log2n,外層循環是n,因此增加函數是nlog2n,因此階次是O(nlog2n)。