他山之石,可以攻玉。👉 👉 My Blog - 小牛肉的個人博客,歡迎來訪~👈 👈
文章目錄
思維導圖
一、線性結構
1. 順序查找(線性查找)O(n)
主要用於在線性表上進行查找
int Search_Seq(int *a,int x){
//a[0]作哨兵,使得循環不必判斷數組是否越界
//因爲滿足i==0時,循環一定會跳出
a[0] = x;
int i;
for(i = 10;a[i]!=x;i--);
return i;
}
注:對於順序查找,不管線性表是有序的還是無序的,成功查找第一個元素的比較次數爲1,成功查找第二個元素的比較次數爲2,依次類推,每個元素查找成功的比較次數只與其位置有關,與是否有序無關。
對有n個元素的有序順序表和無序順序表進行順序查找,討論平均查找長度
2. 折半查找(僅適用於有序的順序表) O(log2n)
int Binary_Search(int *a,int x){
int low = 0, high = 10,mid;
while(low<=high){
mid = (low+high)/2;
cout << a[low] << setw(5) << a[mid] << setw(5) << a[high] << endl;
if(a[mid]==x)
return mid;
else if(a[mid]<x)
low = mid+1;
else
high = mid-1;
}
return -1; //若查找成功不會走到這一步
}
3. 分塊查找(索引順序查找)
塊中元素可無序,塊間元素須有序
二、樹形結構
1. 二叉排序樹
2. 平衡二叉樹
3. B / B+ 樹
B樹的插入刪除操作
插入:
-
插入後該結點關鍵字個數小於等於m-1,直接插入
-
插入後該結點關鍵字個數大與m-1,以該結點的中間元素爲軸進行結點分裂,並將該結點的中間元素上移到其父結點,相應的父結點要增加新分支,即分裂的結點
刪除(葉節點):以3階爲例
-
刪除該關鍵字後所在結點的關鍵字個數 > [m/2]取上整 - 1, 直接刪除關鍵字
-
刪除該關鍵字後所在結點的關鍵字個數 < [m/2]取上整 - 1 且與其相鄰的左(右)兄弟結點夠借 , 父子換位法(兄弟的第一個元素上移到父結點,父結點的最後一個元素下移到要刪除的關鍵字所在的結點。—— 兄弟夠借,父子換位
-
刪除該關鍵字後所在結點的關鍵字個數 < [m/2]取上整 - 1 且與其相鄰的左(右)兄弟結點不夠借 , 則將關鍵字刪除後,將父結點第一個元素下移至要刪除元素所在結點處 並與其兄弟結點合併 —— 兄弟不夠借,父子合併
B樹的建立過程舉例:
三、散列結構
散列表
1. 散列表的定義
散列(哈希)表: 根據關鍵碼值(Key value)而直接進行訪問的數據結構 。根據給定的關鍵字通過散列函數來計算出關鍵字在表中的地址,以加快查找的速度。
2. 散列函數的構造方法
-
直接定址法
H(key) = a*key + b
-
除留取餘法
H(key) = key%p
(p爲不大於m的最大質數)
3. 散列(哈希)衝突
衝突:指的是多個關鍵字映射同一個地址的情況。
4. 處理衝突的方法
1.開放定址法
- 線性探測法(常用,會產生堆積問題)
衝突發生時順序查找下一個位置 - 平方探測法
- 再散列法
2.拉鍊法(所有的同義詞都存儲在一個線性鏈表中)
5. 性能分析
平均查找長度僅依賴於裝填因子,越滿發生衝突的可能性越大。
- ASL成功 (除以 元素的總個數)
- ASL失敗 (除以 P 或 mod後面的數)
四、字符串模式匹配
KMP 算法
int Index_KMP(string s,string T,int next[],int pos){
int i = pos,j = 1; //i代表母表,j代表字表
while(i<=s.length && j<T.length){
if(j==0 || s[j]==T[i]){
i++;
j++;
}
else
j = next[j];
}
if(j>T.length) //匹配成功
return i-T.length;
else
return 0;
}
next 數組算法如下: