小螞蟻學習數據結構(9)——遞歸

專題算法

    遞歸 函數

        定義:一個函數本身直接或間接調用本身spa

    遞歸知足三個條件.net

        1,遞歸必須得有一個明確的終止條件code

        2,該函數所處理的數據規模必須在遞減blog

        3,這個轉化必須是可解的遞歸

    循環和遞歸:內存

        循環能夠使用遞歸實現,遞歸不必定能夠使用循環實現ci

        遞歸:get

            優勢:易於理解

            缺點:速度慢,存儲空間大

        循環:

            缺點:不易理解

            優勢:速度快,存儲空間小


函數的調用

當在一個函數的運行期間調用另外一個函數時,在運行被調用函數以前,系統須要完成三件事:

1,將全部的實際參數,返回地址等信息傳遞給被調函數保存

2,爲被調函數的局部變量(也包括形參)分配存儲空間

3,將控制轉移到被調函數的入口

從被調函數返回主調函數以前,系統也要完成三件事:

1,保存被調函數的返回結果

2,釋放被調函數所佔的存儲空間

3,依照被調函數保存的返回地址將控制轉移到主調函數

當有多個函數相互調用是,按照「後調用先返回」的原則,上述函數之間信息傳遞和控制轉移必須藉助「棧」來實現,即系統將整個程序運行時所需的數據空間安排在一個棧中,每當調用一個函數時,就在棧頂分配一個存儲區,進行壓棧操做,每當一個函數退出時,就釋放他的存儲區,就執行出棧操做,當前運行的函數永遠都在棧的頂部位置。


漢諾塔的遞歸算法

/*
	漢諾塔
	僞算法:
		if( n>1 )
		{
			先把A柱子上的前n-1個盤子從a藉助c移到b
			將a柱子上的第n個盤子直接移到c
			在將b柱子上的n-1個盤子藉助a移到c
		}
*/
# include <stdio.h>

void hanoi(int n, char a, char b, char c)
{
	/*
		若是是1個盤子
			直接將a柱子上的盤子從a轉移到c
		不然
			先將a柱子上的n-1,藉助c柱子轉移到b
			直接把a柱子上的盤子從a轉移到c
			最後將b柱子上的n-1個盤子藉助a轉移到b
	*/
	if( 1 == n )
	{
		printf("將編號爲%d的盤子直接從%c柱子移到%c柱子\n", n, a, c);
	}
	else
	{
		hanoi(n-1, a, c, b);
		printf("將編號爲%d的盤子直接從%c柱子移到%c柱子\n", n, a, c);
		hanoi(n-1, b, a, c);
	}
	
}

int main(void)
{
	//定義三根柱子
	char ch1 = 'A';
	char ch2 = 'B';
	char ch3 = 'C';
	
	int n;
	
	printf("請輸入要移動盤子的個數:");
	scanf("%d",&n);
	
	hanoi(n, ch1, ch2, ch3);
	
	return 0;
}

    雖然遞歸的方式也懂,但這個漢諾塔的遞歸仍是有些迷糊,大腦內存不足,之後還要多參悟一下。


學PHP的小螞蟻 博客 http://my.oschina.net/woshixiaomayi/blog

相關文章
相關標籤/搜索