【棧與隊列】僅用遞歸函數算法來操作一個棧,使棧逆序排列。

功能需求

        一個棧依次壓入1、2、3、4、5,那麼從棧頂到棧底分別爲5、4、3、2、1.如果將這個棧經過系列轉置之後,從棧頂到棧底爲1、2、3、4、5,也就是實現棧中元素的逆序,但是隻能用遞歸函數來實現,而不是使用其他數據結構,也不能使用第二個棧。

詳細解析

        在之前我們曾經使用過兩個棧操作一組數據,經過兩次壓棧出棧操作,我們可以得到逆序隊列。但是題目要求的是主要考察使用遞歸函數來設計,所以我們需要設計出兩組遞歸函數來模仿這兩個棧操作,從而實現逆序棧。

        遞歸函數一:將棧stack的棧底元素返回並移除。具體實現如下代碼中的getAndRemoveLastElement方法。

代碼實現1 

public static int getAndRemoveLastElement (Stack<Integer> stack) {
	// 棧中彈出一個數據,並保存數據
	int result = stack.pop();
	// 判斷棧中元素時候爲空,如果沒有元素這返回
	if (stack.isEmpty()) {
		return result;
	} else {
		// 使用遞歸函數:調用自己本身,循環彈出棧頂元素,直到棧中無元素
		int last = getAndRemoveLastElement(stack);
		// 棧中依次壓入最開始彈出的數據
		stack.push(result);
		// 返回所存的棧數據
		return last;
	}
}

        我們來畫個圖來分析一下這個算法的運行流程

        遞歸函數二:逆序一個棧,那麼我們可以使用第二種方法,也就是題目要求的方法,具體的需要的是reserve方法。可以調用上面的getAndRemoveLastElement()方法。

代碼實現2 


public static void reverse(Stack<Integer> stack) {
	// 棧數據判空操作
	if (stack.isEmtpy()) {
		return;
	}
	// 調用上面的操作函數來刪除棧頂數據得到逆序結果
	int i = getAndRemoveLastElement(stack);
	// 遞歸調用reverse方法
	reverse();
	// 棧底存入棧數據
}

        讓我們也來分析一下這個程序的執行流程

調用遞歸算法保留彈出數據算法流程圖

getAndRemoveLastElement()方法在圖中簡單表示爲get方法,表示移除並返回當前棧元素

總結分析

        當我們碰到使用遞歸來操作循環的時候,一定要考慮到的兩個問題是:第一這個方法執行到什麼時候,從程序的開始到再次調用本方法的時候結束。第二就是當調用完成或者不符合條件而跳出遞歸的時候,調用本方法之後的代碼將是如何繼續運行的。其實你只需要再進行詳細分化一下,不難得出一個規律,遞歸相當於一個while(true)的死循環,也就是你如何使用break的問題,本身這個問題就是讓你熟悉瞭解遞歸算法到底是怎樣的執行流程,其實不難發現,先彈出,再彈出,彈完了之後再去運行之後的保存,就相當於你走路一樣,剛走到終點,不能直接飛回起點吧。ok今天的分享就是這...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章