2014-10-20 57 views
1

我目前完成我的代碼。但由於某種原因,我的遞歸調用在最後沒有被觸發?有沒有某種我偶然想到的特殊代碼?爲什麼我的函數在完成時沒有再次調用(遞歸)?

int max(int arr[], int start, int end) {  
     int greatest = arr[start]; 
     if(start < end) 
     { 

     if(greatest<arr[start]) 
     { 
      greatest = arr[start]; 
     } 
     start++; 
     max(arr, start, end); // Doesn't seem to be triggering since it only returns 8 
     } 
     return greatest; 
}  

int main() 
{ 
    int greatest; 
    int arr[10] = {8,1,2,3,4,5,6,7,8,9}; 
    int start = 0; 
    int end = 10; 
    greatest=max(arr, start, end); 

    pintf("%d\n", greatest); 

} 
+0

你需要複製 - 和 - 將*精確*代碼粘貼到問題中。通過重新輸入它,你已經引入了一個錯字('printf'的'pintf')。我們無法猜測您的問題中的代碼與您詢問的代碼之間可能存在哪些其他差異。 – 2014-10-20 14:54:17

回答

1

你的算法有點搞砸了。例如,greatest<arr[start]永遠不會是真的,因爲您只需設置greatest = arr[start]。這裏有一個評價工作的算法:

#include <stdio.h> 

int max(int arr[], int start, int end) 
{ 
    if (start >= end) { 

     /* Shouldn't get here, but return 0 if we do */ 

     return 0; 
    } 
    else if (end - start == 1) { 

     /* Only one element, so it's the maximum by definiton */ 

     return arr[start]; 
    } 
    else { 

     /* Find the maximum of the rest of the list... */ 

     int greatest = max(arr, start + 1, end); 

     /* ...and return the greater of it, and the first element */ 

     return arr[start] > greatest ? arr[start] : greatest; 
    } 
} 

int main(void) 
{ 
    int arr[] = { 8, 1, 2, 3, 12, 5, 6, 7, 8, 9 }; 
    int start = 0; 
    int end = 10; 
    int greatest = max(arr, start, end); 

    printf("%d\n", greatest); 
} 

與輸出:

[email protected]:~/src/sandbox$ ./max 
12 
[email protected]:~/src/sandbox$ 

讓我們通過它與一個簡單的列表,{1,5,3}。每個縮進級別表示您的遞歸函數調用之一。每次我們看到max(),我們都會上升到一個水平 - 每當我們看到return時,我們就會回到一個水平。

In main(), int greatest = max(list, 0, 3) 

    In call 1: (end - start == 1) is false 
    In call 1: int greatest = max(list, 1, 3) 

     In call 2: (end - start == 1) is false 
     In call 2: int greatest = max(list, 2, 3) 

      In call 3: (end - start == 1) is true 
      In call 3: return arr[2], which is 3 

     Back in call 2: greatest now equals 3 
     Back in call 2: arr[1] == 5, which is > 3, so return arr[1], which is 5 

    Back in call 1: greatest now equals 5 
    Back in call 1: arr[0] == 1, which is not > 5, so return greatest, which is 5 

Back in main(), greatest now equals 5 

記住,每次你看到int greatest時間,這是一個的正在創建不同變量。他們都有相同的名字,但由於他們都在不同的範圍內,他們仍然是不同的。例如,呼叫2中的int greatest與呼叫1中的int greatest完全分開,正如呼叫1中的int greatestmain()中的int greatest完全分開。

編輯:從評論,如果你想最大值的指數爲好,這會做到這一點:

#include <stdio.h> 

int max_index(int arr[], int start, int end) 
{ 
    if (start >= end) { 
     return 0; 
    } 
    else if (end - start == 1) { 
     return start; 
    } 
    else { 
     int greatest = max_index(arr, start + 1, end); 
     return arr[start] > arr[greatest] ? start : greatest; 
    } 
} 

int max(int arr[], int start, int end) 
{ 
    if (start >= end) { 

     /* Shouldn't get here, but return 0 if we do */ 

     return 0; 
    } 
    else if (end - start == 1) { 

     /* Only one element, so it's the maximum by definiton */ 

     return arr[start]; 
    } 
    else { 

     /* Find the maximum of the rest of the list... */ 

     int greatest = max(arr, start + 1, end); 

     /* ...and return the greater of it, and the first element */ 

     return arr[start] > greatest ? arr[start] : greatest; 
    } 
} 

int main(void) 
{ 
    int arr[] = { 8, 1, 2, 3, 12, 5, 6, 7, 8, 9 }; 
    int start = 0; 
    int end = 10; 
    int greatest = max(arr, start, end); 
    int index = max_index(arr, start, end); 

    printf("Greatest value is %d at index %d\n", greatest, index); 
} 

輸出:

[email protected]:~/src/sandbox$ ./max 
Greatest value is 12 at index 4 
[email protected]:~/src/sandbox$ 
+0

當我第一次增加1時,第二次不會是真的嗎? – BeginnerC 2014-10-20 02:57:04

+0

不,因爲你會再次將'arr [start]'分配給'最大'。每次調用函數時都會發生,而不僅僅是第一次。 – 2014-10-20 02:57:43

+0

Aww damn -_-,我現在看... – BeginnerC 2014-10-20 03:00:57

3

只有到max第一個電話 - 一個位於main - 它的返回值實際上分配到任何東西。遞歸調用返回的值立即丟失;他們所做的工作對最終結果毫無意義。您需要將遞歸調用的結果分配給maxgreatest

請記住,每次遞歸調用都會打開一個新範圍,每個範圍都有其自己的greatest變量版本。每次遞歸調用中的賦值只修改它們的變量版本,而不是來自封閉範圍的版本;這意味着第一次調用的版本在取值爲arr[0]後從未設置爲任何值;這是當最外層呼叫恢復時,其值返回到main的版本,無論遞歸調用在兩者之間完成的工作如何。

你也有一個無關的錯誤,這是你遞歸到另一個呼叫到max(和調用內分配給greatest)檢查您是否已經達到了數組的結束,這將溢出超越前數組的末尾,並覆蓋最後的結果(無論發現在那裏)(正如Paul指出的那樣,在與當前值進行比較之前,您還指定greatest,所以比較實際上沒有意義)。您需要移動檢查內的所有內容,以確保不會發生。

+0

我似乎無法包裹我的頭,以遞歸調用的結果爲最大到最大。 – BeginnerC 2014-10-20 02:43:39

+0

當我做得最好= arr [開始]時,我不是已經這麼做嗎?對不起,我現在只是很困惑...... – BeginnerC 2014-10-20 02:45:18

+0

@BeginnerC字面意思是遞歸調用應該寫成'最大=最大(...',就像它出現在'main'中一樣。這聽起來像你不是完全掌握變量範圍和遞歸的作用每一個嵌套的函數調用都有自己的所有局部變量的副本 - 想象它們是「最大{0}」,「最大{1}」等。分配給「最大的{1}」對於最大的{0}'沒有任何效果,它在遞歸調用之前處於相同的狀態。 – Leushenko 2014-10-20 02:47:50

1

我相信遞歸調用被觸發,但沒有做你想做的。你將arr [start]初始化爲最大值(在這種情況下爲8),並且從不分配任何其他值,所以當然你的函數返回8.相反,如果start> = end,你的函數應該返回arr [start] ,否則應返回arr [start]或max(arr,start + 1,end),以較大者爲準。

相關問題