以下是我這次用C++寫的一個有Bug的Merge Sort函式,這個錯誤一開始我並沒有很快找出:
1: void MergeSort(int *A, int p, int r)
2: {
3: int q = 0;
4: if(p<r)
5: {
6: q = ((p+r)/2);
7: MergeSort(A,p,q);
8: MergeSort(A,q+1,r);
9: Merge(A,p,q,r);
10: }
11: }
12: void Merge(int *A, int p, int q, int r)
13: {
14: int n1 = q-p+1; //number of elements of left array. Include q.
15: int n2 = r-q; //number of elements of right array.
16: int L[n1+1];
17: int R[n2+1];
18:
19: for(int i=0;i<n1;i++)
20: {
21: L[i] = A[p+i];
22: }
23: for(int j=0;j<n2;j++)
24: {
25: R[j] = A[q+j];
26: }
27: L[n1] = infinite;
28: R[n2] = infinite;
29: int i = 0; int j = 0;
30:
31: for(int k=p;k<=r;k++)
32: {
33: if(L[i]<=R[j])
34: {
35: A[k] = L[i];
36: i++;
37: }
38: else
39: {
40: A[k] = R[j];
41: j++;
42: }
43: }
44: }
這個程式執行結果會是錯的,原因是第25行:
25: R[j] = A[q+j];
在複製陣列內容到R array時,應該要寫:
25: R[j] = A[q+j+1];
因為L陣列裡面已經包含index為 q 的element了。只要更改這一行,就是一個完整的Merge Sort的code了。我將這種bug歸類為"陣列index的錯誤問題"。這種bug通常簡單,但簡單的錯誤難免發生。為了避免類似的錯誤,我之後將會使用特定格式的註解(先將此註解法則命名為Uncle註解法好了...),來表示出陣列操作時的操作範圍,例如
,以此Merge Sort為例:
R[j] = A[q+j+1]; // A[] : q+1<->q+n2 // j : 0<->n2-1 // total # : n2
上面這一行的註解中 A[] : q+1<->q+n2代表陣列A的索引值在for迴圈中從q+1一直trace到q+n2範圍,每一部分的註解描述用雙斜線 "//" 分開,j : 0<->n2-1代表j從0一直到n2-1,最後 total # : n2代表整體迴圈操作次數有n2+1次操作。
一直以來我都想定義一個共同的註解規範,能夠註解的格式統一,方便debug,我希望從現在開始實現這個願望,目前註解法的格式還在制定中。