目錄python
客觀世界中許多事物存在層次關係算法
其中,人類社會家譜以下圖所示:數組
經過上述所說的分層次組織,可以使咱們在數據的管理上有更高的效率!那麼,對於數據管理的基本操做——查找,咱們如何實現有效率的查找呢?數據結構
查找:根據某個給定關鍵字K,從集合R中找出關鍵字與K相同的記錄spa
靜態查找:集合中記錄是固定的,即對集合的操做沒有插入和刪除,只有查找3d
動態查找:集合中記錄是動態變化的,即對集合的操做既有查找,還可能發生插入和刪除(動態查找不在咱們考慮範圍內)指針
/* c語言實現 */ int SequentialSearch (StaticTable *Tbl, ElementType K) { // 在表Tbl[1]~Tb1[n]中查找關鍵字爲K的數據元素 int i; Tbl->Element[0] = K; // 創建哨兵,即沒找到能夠返回哨兵的索引0表示未找到 for (i = Tbl->Length; Tbl->Element[i] != K; i--); // 查找成功返回所在單元下標;不成功放回0 return i; }
順序查找算法的時間複雜度爲O(n)code
假設n個數據元素的關鍵字知足有序(好比:小到大),即\(k_1<k_2<\cdots<k_n\),而且是連續存放(數組),那麼能夠進行二分查找。blog
例:假設有13個數據元素,按關鍵字由小到大順序存放。二分查找關鍵字爲444的數據元素過程以下圖:索引
仍然以上面13個數據元素構成的有序線性表爲例,二分查找關鍵字爲43的數據元素以下圖:
/* c語言實現 */ int BinarySearch (StaticTable *Tbl, ElementType K) { // 在表中Tbl中查找關鍵字爲K的數據元素 int left, right, mid, NoFound = -1; left = 1; // 初始左邊界 right = Tbl->Length; // 初始右邊界 while (left <= right) { mid = (left + right) / 2; // 計算中間元素座標 if (K < Tbl->Element[mid]) right = mid - 1; // 調整右邊界 else if (K > Tbl->Element[mid]) left = mid + 1; // 調整左邊界 else return mid; // 查找成功,返回數據元素的下標 } return NotFound; // 查找不成功,返回-1 }
# python語言實現 def binary_chop(alist, data): n = len(alist) first = 0 last = n - 1 while first <= last: mid = (last + first) // 2 if alist[mid] > data: last = mid - 1 elif alist[mid] < data: first = mid + 1 else: return True return False
二分查找算法具備對數的時間複雜度O(logN)
二分查找算法雖然解決了查找的時間複雜度問題,可是對於數據的插入和刪除確是O(n)的,所以有沒有一種數據結構,既能夠減小數據查找的時間複雜度,又能夠減小數據的插入和刪除的複雜度呢?
除了使用上述兩個方法進行關鍵字的查找,咱們還能夠經過二叉樹這種數據結構完成關鍵字的查找。
從上圖能夠看出,若是咱們須要尋找數字8,能夠經過如下4步實現(可能看不懂,將來會看得懂):
樹(Tree):\(n(n\geq{0})\)個結點構成的有限集合。
牢記樹有如下3個特性:
兄弟結點(Sibling):具備同一父結點的各結點彼此是兄弟結點
路徑和路徑長度:從結點\(n_1\)到\(n_k\)的路徑爲一個結點序列\(n_1 , n_2 ,\cdots, n_k\) , \(n_i\)是\(n_{i+1}\)的父結點。路徑所包含邊的個數爲路徑的長度
子孫結點(Descendant):某一結點的子樹中的全部結點是這個結點的子孫
結點的層次(Level):規定根結點在1層,其它任一結點的層數是其父結點的層數加1
樹的深度(Depth):樹中全部結點中的最大層次是這棵樹的深度
上圖所示樹的鏈表表示法有很大的缺陷,假設樹的深度很是大,而且不能保證全部樹的子結點都有3個,那麼會形成很大程度的浪費。
爲了解決樹的普通鏈表表示會有空間的浪費的缺陷,咱們能夠把鏈表的指針設置兩個連接,一個連接指向兒子結點,另外一個連接指向兄弟結點,以下圖所示:
上圖所示的樹的表示方法,已經足夠完美了,可是若是咱們把鏈表表示的樹旋轉45°角,會發現以下圖所示:
通過45°角的旋轉,咱們會發現一顆二叉樹(一個結點至多擁有2個子結點的樹),也就是說最普通的樹其實能夠經過二叉樹表示,也就是說咱們只要把二叉樹研究透了,咱們即研究透了樹。