簡介: 有哪些常見的數據結構?基本操做是什麼?常見的排序算法是如何實現的?各有什麼優缺點?本文簡要分享算法基礎、常見的數據結構以及排序算法,給同窗們帶來一堂數據結構和算法的基礎課。html
數據結構是數據的組織、管理和存儲格式,其使用目的是爲了高效的訪問和修改數據。算法
數據結構是算法的基石。若是把算法比喻成美麗靈動的舞者,那麼數據結構就是舞者腳下廣闊而堅實的舞臺。數組
物理結構就像人的血肉和骨骼,看得見,摸得着,實實在在,如數組、鏈表。性能優化
邏輯結構就像人的思想和精神,它們看不見、摸不着,如隊列、棧、樹、圖。網絡
大O表示法(漸進時間複雜度):把程序的相對執行時間函數T(n)簡化爲一個數量級,這個數量級能夠是n、n^二、logN等。數據結構
推導時間複雜度的幾個原則:多線程
時間複雜度對比:O(1) > O(logn) > O(n) > O(nlogn) > O(n^2)。數據結構和算法
不一樣時間複雜度算法運行次數對比:函數
常量空間 O(1):存儲空間大小固定,和輸入規模沒有直接的關係。性能
線性空間 O(n):分配的空間是一個線性的集合,而且集合大小和輸入規模n成正比。
二維空間 O(n^2):分配的空間是一個二維數組集合,而且集合的長度和寬度都與輸入規模n成正比。
遞歸空間 O(logn):遞歸是一個比較特殊的場景。雖然遞歸代碼中並無顯式的聲明變量或集合,可是計算機在執行程序時,會專門分配一塊內存空間,用來存儲「方法調用棧」。執行遞歸操做所須要的內存空間和遞歸的深度成正比。
穩定:若是a本來在b前面,而a=b,排序以後a仍然在b的前面。
不穩定:若是a本來在b的前面,而a=b,排序以後 a 可能會出如今 b 的後面。
首先要明確:特定算法解決特定問題。
其中,字符串、查找、排序算法是最基礎的算法。
1)什麼是數組?
數據是有限個相同類型的變量所組成的有序集合。數組中的每個變量被稱爲元素。
2)數組的基本操做?
讀取O(1)、更新O(1)、插入O(n)、刪除O(n)、擴容O(n)。
1)什麼是鏈表?
鏈表是一種在物理上非連續、非順序的數據結構,由若干個節點組成。
單向鏈表的每個節點又包含兩部分,一部分是存放數據的變量data,另外一部分是指向下一個節點的指針next。
2)鏈表的基本操做?
讀取O(n)、更新O(1)、插入O(1)、刪除O(1)。
3)鏈表 VS 數組
數組:適合多讀、插入刪除少的場景。
鏈表:適用於插入刪除多、讀少的場景。
1)什麼是棧?
棧是一種線性邏輯數據結構,棧的元素只能後進先出。最先進入的元素存放的位置叫作棧底,最後進入的元素存放的位置叫棧頂。
一個比喻,棧是一個一端封閉一端的開放的中空管子,隊列是兩端開放的中空管子。
2)如何實現棧?
數組實現:
鏈表實現:
3)棧的基本操做
入棧O(1)、出棧O(1)。
4)棧的應用?
1)什麼是隊列?
一種線性邏輯數據結構,隊列的元素只能後進後出。隊列的出口端叫作隊頭,隊列的入口端叫作隊尾。
2)如何實現隊列?
數組實現:
鏈表實現:
3)隊列的基本操做?
入隊 O(1)、出隊 O(1)。
4)隊列的應用
1)什麼是哈希表?
一種邏輯數據結構,提供了鍵(key)和值(value)的映射關係。
2)哈希表的基本操做?
寫入:O(1)、讀取:O(1)、擴容O(n)。
3)什麼是哈希函數?
哈希表本質上是一個數組,只是數組只能根據下標,像a[0] a[1] a[2] a[3] 這樣來訪問,而哈希表的key則是以字符串類型爲主的。
經過哈希函數,咱們能夠把字符串或其餘類型的key,轉化成數組的下標index。
如給出一個長度爲8的數組,則:
當key=001121時,
index = HashCode ("001121") % Array.length = 7
當key=this時,
index = HashCode ("this") % Array.length = 6
4)什麼是哈希衝突?
不一樣的key經過哈希函數得到的下標有多是相同的,例如002936這個key對應的數組下標是2,002947對應的數組下標也是2,這種狀況就是哈希衝突。
5)如何解決哈希衝突?
開放尋址法:例子Threadlocal。
鏈表法:例子Hashmap。
1)什麼是樹?
樹(tree)是n(n≥0)個節點的有限集。
當n=0時,稱爲空樹。在任意一個非空樹中,有以下特色:
2)樹的遍歷?
(1)深度優先
前序:根節點、左子樹、右子樹。
中序:左子樹、根節點、右子樹。
後序:左子樹、右子樹、根節點。
實現方式:遞歸或棧。
(2)廣度優先
層序:一層一層遍歷。
實現方式:隊列。
1)什麼是二叉樹?
二叉樹(binary tree)是樹的一種特殊形式。二叉,顧名思義,這種樹的每一個節點最多有2個孩子節點。注意,這裏是最多有2個,也可能只有1個,或者沒有孩子節點。
2)什麼是滿二叉樹?
一個二叉樹的全部非葉子節點都存在左右孩子,而且全部葉子節點都在同一層級上,那麼這個樹就是滿二叉樹。
3)什麼是徹底二叉樹?
對一個有n個節點的二叉樹,按層級順序編號,則全部節點的編號爲從1到n。若是這個樹全部節點和一樣深度的滿二叉樹的編號爲從1到n的節點位置相同,則這個二叉樹爲徹底二叉樹。
1)什麼是二叉查找樹?
二叉查找樹在二叉樹的基礎上增長了如下幾個條件:
2)二叉查找樹的做用?
3)二叉樹的實現方式?
1)什麼是二叉堆?
二叉堆是一種特殊的徹底二叉樹,它分爲兩個類型:最大堆和最小堆。
2)二叉堆的基本操做?
(1)插入:插入最末,節點上浮。
(2)刪除:刪除頭節點,尾節點放到頭部,再下沉。
(3)構建二叉堆:二叉樹==》二叉堆,全部非葉子節點依次下沉。
3)二叉堆的實現方式?
數組:
1)算法描述
冒泡排序是一種簡單的排序算法。它重複地走訪過要排序的數列,一次比較兩個元素,若是它們的順序錯誤就把它們交換過來。走訪數列的工做是重複地進行直到沒有再須要交換,也就是說該數列已經排序完成。這個算法的名字由來是由於越小的元素會經由交換慢慢「浮」到數列的頂端。
2)實現步驟
3)優缺點
4)適用範圍
數據已經基本有序,且數據量較小的場景。
5)場景優化
(1)已經有序了還再繼續冒泡問題
(2)部分已經有序了,下一輪的時候但仍是會被遍歷
(3)只有一個元素不對,但須要走徹底部輪排序
1)算法描述
歸併排序是創建在歸併操做上的一種有效的排序算法。該算法是採用分治法的一個很是典型的應用。遞歸的把當前序列分割成兩半(分割),在保持元素順序的同時將上一步獲得的子序列集成到一塊兒(歸併),最終造成一個有序數列。
2)實現步驟
圖源:http://www.javashuo.com/article/p-nkdsmljg-cd.html
3)優缺點
優勢:
缺點:
4)適用範圍
大數據量且指望要求排序穩定的場景。
1)算法描述
快速排序使用分治法策略來把一個序列分爲較小和較大的2個子序列,而後遞歸地排序兩個子序列,以達到整個數列最終有序。
2)實現步驟
3)優缺點
優勢:
缺點:
4)適用範圍
大數據量且不要求排序穩定的場景。
5)場景優化
(1)每次的基準元素都選中最大或最小元素
(2)數列含有大量重複數據
(3)快排的性能優化
1)算法描述
堆排序(Heapsort)是指利用堆這種數據結構所設計的一種排序算法。堆積是一個近似徹底二叉樹的結構,並同時知足堆積的性質:即子結點的鍵值或索引老是小於(或者大於)它的父節點。
2)實現步驟
3)優缺點
優勢:
缺點:
4)適用範圍
數據量大且數據呈流式輸入的場景。
5)爲何實際狀況快排比堆排快?
堆排序的過程可知,創建最大堆後,會將堆頂的元素和最後一個元素對調,而後讓那最後一個元素從頂上往下沉到恰當的位置,由於底部的元素必定是比較小的,下沉的過程當中會進行大量的近乎無效的比較。因此堆排雖然和快排同樣複雜度都是O(NlogN),但堆排複雜度的常係數更大。
1)算法描述
計數排序不是基於比較的排序算法,其核心在於將輸入的數據值轉化爲鍵存儲在額外開闢的數組空間中。做爲一種線性時間複雜度的排序,計數排序要求輸入的數據必須是有肯定範圍的整數。
2)實現步驟
3)優缺點
優勢:
缺點:
4)適用範圍
數列元素是整數,當k不是很大且序列比較集中時適用。
5)場景優化
(1)數字不是從0開始,會存在空間浪費的問題
1)算法描述
桶排序是計數排序的升級版。它利用了函數的映射關係,高效與否的關鍵就在於這個映射函數的肯定。實現原理:假設輸入數據服從均勻分佈,將數據分到有限數量的桶裏,每一個桶再分別排序(有可能再使用別的排序算法或是以遞歸方式繼續使用桶排序進行排序)。
2)實現步驟
3)優缺點
優勢:
缺點:
4)適用範圍
數據服從均勻分佈的場景。
隨機生成區間0 ~ K之間的序列,共計N個數字,利用各類算法進行排序,記錄排序所需時間。
參考內容及圖源
[1]《漫畫算法:小灰的算法之旅》
[2]《算法(第4版)》
[3]《算法圖解》
[4]《劍指Offer》
[5]十大經典排序算法(動圖演示)
http://www.javashuo.com/article/p-apvjfrqu-dq.html
[6]維基百科
https://zh.wikipedia.org/wiki/Wikipedia:%E9%A6%96%E9%A1%B5