資料結構第七章學習小結
第七章的知識總結:
作業:
判斷題:
1.在散列表中,所謂同義詞就是具有相同雜湊地址的兩個元素。(2分) T F
原因:應該是該兩個不同元素,具有同一雜湊地址才是同義詞。
2.在度量搜尋引擎的結果集的相關度時,召回率很低意味著大多數相關的文件沒有被找到。(2分)T F
3.在度量搜尋引擎的結果集的相關度時,準確率很低意味著找出的大部分文件是無關的。(2分)T F
召回率(Recall Rate,也叫查全率)是檢索出的相關文件數和文件庫中所有的相關文件數的比率,衡量的是檢索系統的查全率;精度是檢索出的相關文件數與檢索出的文件總數的比率,衡量的是檢索系統的查準率。
(關於準確率和召回率:https://blog.csdn.net/yechaodechuntian/article/details/37394967)
選擇題:
選擇題沒有太多挖坑的地方,主要是一些重要的、容易混淆的概念
1.在下列查詢的方法中,平均查詢長度與結點個數無關的查詢方法是:(2分)
利用二叉搜尋樹
2.(neuDS)對線性表進行二分查詢時,要求線性表必須( )(2分)
以連結方式儲存,且結點按關鍵字值有序排列
3.若查詢每個元素的概率相等,則在長度為n的順序表上查詢任一元素的平均查詢長度為()。(2分)
(n-1)/2
原因:第一個元素只用比較一次就可以找到,最後一個要比較n次,所以平均查詢長度為(n+1)/2.
4.(neuDS)當採用分塊查詢時,資料的組織方式為( )。(2分)
資料分成若干塊,每塊內資料必須有序,但塊間不必有序
5.__是HASH查詢的衝突處理方法:(2分)
開放地址法
這些都是平常不太容易注意到的點,這些選擇題幫我們很好地幫我們總結了一下易混淆的知識點。
3.程式設計題
這一道主要就是考察運用雜湊演算法的能力。一定要注意表長是否是素數,不是的話要找出合適的素數。找素數的兩種方法:
第一種方法:
1 int NextPrime(int n) //求素數 2 {3 int p; 4 if(n==1) return 2; 5 if(n%2==1) 6 { 7 p = n+2; 8 } 9 else p = n+1; 10 while (1) 11 { 12 int i; 13 for(i=3; i*i<=p; i+=2) 14 { 15 if(p%i == 0) break; 16 } 17 if(i*i > p) break; 18 else p += 2; 19 } 20 return p; 21 }
這種方法會比較難理解,但是判斷表長和找素數是在一個函式裡完成的,看起來會整潔很多
第二種方法:
1 bool prime(int a)//返回值為布林型別,判斷素數 2 { 3 int i, k; 4 if(a==0||a==1) return 0; 5 k=(int)sqrt(a);//k=根號a 6 for(i=2; i<=k; i++) 7 if(a%i==0) return 0; 8 return 1; 9 } 10 int get_prime(int a) 11 { 12 while(!prime(a)) 13 { 14 a++; 15 } 16 return a; 17 }
這種方法簡單易懂,和上學期學習的判斷素數的方法很像,推薦同學們使用
我的程式碼最開始有三個測試點報錯,後來改了很久,才發現是一些很小但很容易錯的地方
第一個:
1 int Hash (int Key, int p) 2 { 3 int a = Key % p; 4 for(int i = 0; i <= p; i++) //這裡應該是i<p,i的取值應該在0 - (p-1),等於p的時候相當於回到了第一次迴圈,沒有意義 5 { 6 int b = (a + i*i) % p; 7 if(!HashTable[b]) 8 { 9 HashTable[b] = 1; 10 return b; 11 } 12 } 13 return -1; 14 }
第二個:
1 int Hash (int Key, int p) 2 { 3 int a = Key % p; 4 for(int i = 0; i < p; i++) 5 { 6 a = (a + i*i) % p; //這裡應該單獨定義一個變數來存值,因為每次應該都是在原來數的基礎上進行增加的操作 7 if(!HashTable[a]) 8 { 9 HashTable[a] = 1; 10 return a; 11 } 12 } 13 return -1; 14 }
正確的程式碼:
1 int Hash (int Key, int p) 2 { 3 int a = Key % p; 4 for(int i = 0; i < p; i++) 5 { 6 int b = (a + i*i) % p; 7 if(!HashTable[b]) 8 { 9 HashTable[b] = 1; 10 return b; 11 } 12 } 13 return -1; 14 }
第三個,不要想著直接用char作為Hash函式的返回值,因為char型別只有八位且 ‘0’ + 10 != ‘10’,所以將返回型別設為int,輸出時按返回值的情況分別進行輸出。
該題的完整程式碼:
1 #include <iostream> 2 #include<cmath> 3 using namespace std; 4 5 int HashTable[11000], a[11000]; 6 7 int NextPrime(int n) //求素數 8 { 9 int p; 10 if(n==1) return 2; 11 if(n%2==1) 12 { 13 p = n+2; 14 } 15 else p = n+1; 16 while (1) 17 { 18 int i; 19 for(i=3; i*i<=p; i+=2) 20 { 21 if(p%i == 0) break; 22 } 23 if(i*i > p) break; 24 else p += 2; 25 } 26 return p; 27 } 28 29 int Hash (int Key, int p) 30 { 31 int a = Key % p; 32 for(int i = 0; i < p; i++) 33 { 34 int b = (a + i*i) % p; 35 if(!HashTable[b]) 36 { 37 HashTable[b] = 1; 38 return b; 39 } 40 } 41 return -1; 42 } 43 44 int main() 45 { 46 int n, t; 47 cin >> t >> n; 48 t = NextPrime(t); 49 for(int i=0; i<n; i++) 50 { 51 cin >> a[i]; 52 HashTable[i] = 0; 53 } 54 int p; 55 p = Hash(a[0], t); 56 if(p<0) cout << "-"; 57 else cout << p; 58 for(int i=1; i<n; i++) 59 { 60 p = Hash(a[i], t); 61 if(p<0) cout << " -"; 62 else cout << " " << p; 63 } 64 return 0; 65 }
實踐1的程式設計題看起來不是特別難,但是一定要注意幾種情況:
1.當要找的數小於全部數的時候,輸出0,而不是-1;
2.當要找的數大於全部數的時候,可以不用進行比較,直接返回-1就好了;
程式碼如下:
1 #include <iostream> 2 using namespace std; 3 4 typedef struct 5 { 6 int key; 7 }ElemType; 8 9 typedef struct 10 { 11 ElemType *R; 12 int length; 13 }SSTable; 14 15 void init(SSTable &ST, int n) 16 { 17 ST.length = n; 18 ST.R = new ElemType[n+1]; 19 } 20 21 int Search_Bin(SSTable ST, int key) 22 { 23 int low = 0; 24 int high = ST.length-1; 25 int mid; 26 if(key>ST.R[high].key) return -1; 27 else 28 { 29 while(low<=high) 30 { 31 mid = (low + high)/2; 32 if(key<=ST.R[mid].key) high = mid - 1; 33 else low = mid + 1; 34 } 35 return low; 36 } 37 } 38 39 int main() 40 { 41 int n; 42 SSTable ST; 43 44 cin >> n; 45 46 int i, m, x; 47 init(ST, n); 48 49 for(i=0; i<n; i++) 50 { 51 cin >> ST.R[i].key; 52 } 53 54 cin >> x; 55 56 if(Search_Bin(ST, x)!=-1) cout << Search_Bin(ST, x) <<endl; 57 else cout << "-1" <<endl; //分情況進行輸出 58 59 delete []ST.R; //申請了空間一定要記得釋放哦 60 61 return 0; 62 }
第七章對寫程式碼很有幫助,查詢也是大部分程式碼裡需要用到的演算法,感覺學好了查詢,用對查詢的方法,對提高程式碼的時間複雜度很有幫助。
希望下一章打程式碼的時候可以細心一些,多注意一些小的細節。