1. 程式人生 > 實用技巧 >資料結構第七章學習小結

資料結構第七章學習小結

第七章的知識總結:

作業:

判斷題:

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 }

第七章對寫程式碼很有幫助,查詢也是大部分程式碼裡需要用到的演算法,感覺學好了查詢,用對查詢的方法,對提高程式碼的時間複雜度很有幫助。

希望下一章打程式碼的時候可以細心一些,多注意一些小的細節。