Java遞迴執行的機制:遞迴的微觀解讀圖文分析
本文講述了Java遞迴執行的機制:遞迴的微觀解。分享給大家供大家參考,具體如下:
前言:在java遞迴基礎與遞迴的巨集觀語意和java連結串列的天然遞迴結構性質中我們分別通過陣列以及連結串列對遞迴進行了應用,那時我們只是對遞迴進行了巨集觀理解--遞迴是將問題化為更小問題的子過程。這一節我們對在4.1節中遞迴在陣列中的應用和4.2節中遞迴在連結串列中的應用進行微觀解讀:
一.關於4.1節中遞迴在陣列中的應用
1) 我們先來看看4.1節中的程式碼實現,如下圖:
為了更好的進行分析,我們將上述程式碼的最後一句進行拆分,拆分結果如下:
此時 n=arr.length=2:
2)現在我們對已經拆分的程式碼進行分析為此來說明:遞迴函式的呼叫,本質就是函式呼叫。
為了分析簡單,我們使用只有兩個元素的陣列 arr=[6,10]
第一次呼叫:sum(arr,0)
使用sun(arr,0)進行呼叫,進入方法體之後,由於不滿足遞迴的基本條件,進而繼續呼叫sum(arr,1)方法,如下:
第二次呼叫:sum(arr,1)
使用sun(arr,1)進行呼叫,進入方法體之後,由於不滿足遞迴的基本條件,進而繼續呼叫sum(arr,2)方法,此時呼叫過程如下:
當呼叫sum(arr,2)時,由於此時已經滿足了遞迴的基本條件,結果直接返回0,回到上一次中斷的位置,也就是下圖中呼叫sum(arr,1) 方法中的sum(arr,l+1)處,如下圖:
程式碼從中斷處繼續向下執行,返回arr[1]=10,x=0因此res=10,此時返回值為res=10;
此時程式碼也將回到sum(arr,1)父親的呼叫中,也就是sum(arr,0)中。
程式碼從中斷處繼續向下執行,返回arr[0]=6,x=10因此res=16,此時返回值為res=16;
通過遞迴得到了我們最終的結果為16。
從上述的過程中印證了:遞迴函式的呼叫,本質就是函式呼叫(自身函式)---也就是使用不同的引數,執行相同的邏輯。
二、關於4.2節中遞迴在連結串列中的應用(刪除連結串列中指定的所有元素值)
1)我們先來看看4.2節中的程式碼實現,如下圖:
為了分析的方便,我們對方法體中的程式碼做一個簡單的標識1,2,3,結果如下圖:
2)為了分析的簡便,我們來進行模擬呼叫,對6--->7--->8--->null 刪除元素為7的節點。
注意:下面的分析中我們使用1,3這樣的編號,表示程式碼執行到的位置
第一次呼叫:
首先傳入頭結點為6的連結串列,由於不滿足遞迴的基本結束條件,再一次觸發第二次呼叫,此時連結串列變為頭結點為7的連結串列:
第二次呼叫:
此時連結串列的頭結點變為7,由於不滿足遞迴的基本結束條件,再一次觸發第三次呼叫,此時連結串列變為頭結點為8的連結串列:
第三次呼叫:
此時連結串列的頭結點變為8,由於不滿足遞迴的基本結束條件,再一次觸發第四次呼叫,此時連結串列變為空連結串列:
第四次呼叫中,由於此時已經滿足了遞迴的基本條件,回到上一次中斷的位置也就是2的位置,返回值為null,如下:
此時的連結串列為頭結點為8的連結串列,如上圖黃色區域,執行第三步程式碼之後,返回的結果為為頭結點為8的連結串列,即為8-->null,並將該結果返回到上一步呼叫,也就是標號為2的地方,得到結果為7-->8-->null的連結串列。
然後繼續執行第三步,此時連結串列7-->8-->null滿足刪除條件,也就是head.val=val=7,將執行head.next,返回最終結果為8-->null,如下:
回到父級呼叫的中斷位置,得到的結果為6-->8--->null,然後執行第三步程式碼,判斷此時的連結串列的head.val是否等於val=7,此時的連結串列不滿足,直接返回head,也就是6--8-->null
到此遞迴呼叫得以結束,完成過程如下:
遞迴的呼叫是由代價的:函式呼叫(時間開銷)+系統棧空間,但是使用遞迴書寫邏輯是更為簡單的。
更多關於java演算法相關內容感興趣的讀者可檢視本站專題:《Java資料結構與演算法教程》、《Java操作DOM節點技巧總結》、《Java檔案與目錄操作技巧彙總》和《Java快取操作技巧彙總》
希望本文所述對大家java程式設計有所幫助。