在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言,你真的懂遞歸了嗎?

冬至子 ? 來源:嵌入式Linux ? 作者:寫代碼的籃球球癡 ? 2023-06-06 15:24 ? 次閱讀

什么是遞歸?

要說到遞歸如果不說棧的話,我覺得有點不合適,遞歸特點就是不斷的調用同一個函數,如果這個函數沒有一個遞歸界限,那么就是死循環了,所以討論遞歸,就必須要討論遞歸的界限,就是限定這個遞歸調用多少次。

我們看一個例子

#include "stdio.h"

int digui(unsigned long count )
{
	if(count > 0){
		count --;
		printf("%d \\n",count);
		digui(count);
	}
	return 1;
}

int main()
{
	digui(10);
	return (100);
}

這個遞歸函數的限定判讀是

if(count > 0){

所以他的調用順序可以用這個圖示來說明

圖片

這個過程叫做遞去,也就是壓棧的過程,既然有壓棧的過程,那么就有出棧的過程,出棧的過程就是

if(count > 0){

判斷不成功后,就會出棧了。如下圖所示

圖片

一共能執行多少次遞歸?

我們上面說到了,既然遞歸使用了棧,那么系統的棧的大小肯定是有極限的,不可能系統給你分配無極限的棧的大小,我看一些文章說棧大小是64K。

還是上面那個例子,我把傳入數據設置為很大執行看看。

#include "stdio.h"

int tigui(unsigned long count )
{
	if(count > 0){
		count --;
		printf("%d \\n",count);
		tigui(count);
	}
	return 1;
}

int main()
{
	tigui(900000);
	return (100);
}

執行結果

圖片

所以說遞歸次數肯定是有限定的了。

遞歸求階乘

使用遞歸求階乘是很經典的方法,我們看一下代碼。

#include< stdio.h >
int fact(unsigned long n); //聲明階乘fact函數
int main(){
	 unsigned long x;
	 scanf("%d",&x);
	 x = fact(x);//調用函數返回int值
	 printf("%ld\\n",x);
	 return (0);
}
int fact(unsigned long n){//定義階乘函數
	if(n==1) return 1;//輸入的參數是1,直接返回1
	else return n*fact(n-1);//遞歸算法
}

執行結果

圖片

單看代碼我覺得還是有點拗口 我們看個圖片來看他的調用,假設我們要求的是 5 的階乘

圖片

遞歸和漢諾塔

漢諾塔: 漢諾塔(又稱河內塔)問題是源于印度一個古老傳說的益智玩具。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。

圖片

如果是這樣的漢諾塔,我覺得應該每個人都覺得很簡單吧,只需要三步就可以完成移動。

  • 1、把小圓盤放到第三根柱子上
  • 2、把中圓盤放到第二根柱子上
  • 3、把小圓盤放到第二根柱子上
  • 4、把大圓盤放到第三根柱子上
  • 5、把小圓盤放到第一根柱子上
  • 6、把中圓盤放到第三根柱子上
  • 7、把小圓盤放到第三根柱子上

如圖所示

圖片

剖析我們上面是細分的方法,移動的核心思想分為三步。

  • 1、把第一個柱子上的n-1圓盤移動到第二個柱子上。
  • 2、把第一個柱子的第n個圓盤移動到第三個柱子上。
  • 3、把第二個柱子的n-1個圓盤移動到第三個柱子。

圖片

所以遞歸就出現了

  • 1、把第一個柱子上的n-1圓盤移動到第二個柱子上「 遞歸實現 」。
  • 2、把第一個柱子的第n個圓盤移動到第三個柱子上。
  • 3、把第二個柱子的n-1個圓盤移動到第三個柱子「 遞歸實現 」。

C語言代碼實現

#include < stdio.h >
#include < windows.h >
void Hanoi(int n, char a,char b,char c);
void Move(int n, char a, char b);
int count;
int main()
{
    int n=8;
    printf("漢諾塔的層數:\\n");
    scanf(" %d",&n);
    Hanoi(n, 'A', 'B', 'C');
    printf("Exiting main...\\n");
    return 0;
}
void Hanoi(int n, char a, char b, char c)
{
    if (n == 1)
    {
        Move(n, a, c);
    }
    else
    {
        Hanoi(n - 1, a, c, b);/*把 n-1 從 a 柱子放到 b 柱子上面*/
        Move(n, a, c);        /*把 n 從 a 移動到 c 上*/
        Hanoi(n - 1, b, a, c);/*把n - 1 通過 a 的輔助作用 從 b 移動到 c 上*/
    }
}
void Move(int n, char a, char b)
{
    count++;
    printf("第%d次移動 Move %d: 從 %c 位置 移動到 %c !\\n",count,n,a,b);
}

輸出如圖所示

圖片

加強版修改

加強了下軟件寫法,好好看代碼,寫的有點太快,沒細想,后面再完善。

#include < stdio.h >

/*柔性數組*/
typedef struct _soft_array{
	int len;
	int array[];
}soft_array;

/*漢諾塔結構體*/
typedef struct _hannuo{
	soft_array *p_data;
	char name;
}hannuo;

hannuo * han_a = NULL;
hannuo * han_b = NULL;
hannuo * han_c = NULL;

void hannoiii(int n,hannuo * a,hannuo * b,hannuo * c);
void moveiii (int n,hannuo * a,hannuo * c);

int total;

void printf_han_data(hannuo * han)
{
	int i = 0;
	printf("%c: ",han- >name);
	/*輸出漢諾塔的數據*/
	for(i = 0;i< han- >p_data- >len;i++)
	{
		printf("%d-",han- >p_data- >array[i]);
	}
	printf("\\n");	
}


int main()
{
	int i = 0;
	int n = 0;

	scanf(" %d",&n);
	total = n;
	/*定義三個漢諾塔節點*/
	han_a = (hannuo *)malloc(sizeof(hannuo));
	han_a- >name = 'A';
	han_a- >p_data = (soft_array*)malloc(sizeof(soft_array)+sizeof(int)*n);
	han_a- >p_data- >len = n;
	
	/*數據原來在第一根柱子上*/
	for(i = 0;i< n;i++)
	{
		han_a- >p_data- >array[i] = i+1;
	}
	printf_han_data(han_a);
	
	/*初始化第二根柱子*/
	han_b = (hannuo *)malloc(sizeof(hannuo));
	han_b- >name = 'B';
	han_b- >p_data = (soft_array*)malloc(sizeof(soft_array)+sizeof(int)*n);
	memset(han_b- >p_data,0,sizeof(soft_array)+sizeof(int)*n);
	han_b- >p_data- >len = n;
	printf_han_data(han_b);
	/*初始化第三根柱子*/
	han_c = (hannuo *)malloc(sizeof(hannuo));
	han_c- >name = 'C';
	han_c- >p_data = (soft_array*)malloc(sizeof(soft_array)+sizeof(int)*n);
	memset(han_c- >p_data,0,sizeof(soft_array)+sizeof(int)*n);
	han_c- >p_data- >len = n;
	printf_han_data(han_c);
	printf("------------------------\\n");
	hannoiii(n,han_a,han_b,han_c);
	

	printf("\\n");
    return 0;
}

void hannoiii(int n,hannuo * a,hannuo * b,hannuo * c)
{
	if(n == 1)
	{
		a- >p_data- >array[0] = 0;
		c- >p_data- >array[0] = 1;
		printf_han_data(han_a);
		printf_han_data(han_b);
		printf_han_data(han_c);
		printf("------------------------\\n");
	}
	else
	{
		hannoiii(n - 1, a, c, b);/*把 n-1 從 a 柱子放到 b 柱子上面*/
        moveiii(n, a, c);        /*把 n 從 a 移動到 c 上*/
		printf_han_data(han_a);
		printf_han_data(han_b);
		printf_han_data(han_c);
		printf("------------------------\\n");
        hannoiii(n - 1, b, a, c);/*把n - 1 通過 a 的輔助作用 從 b 移動到 c 上*/
	}
}

void moveiii (int n,hannuo * a,hannuo * c)
{
    int i = 0;
    int tmp = a- >p_data- >array[n-1];
	a- >p_data- >array[n-1] = 0;
	#if 1
	c- >p_data- >array[n-1] = tmp;
	#else
	for(i = 0;i < total;i++)
	{
	    if(c- >p_data- >array[i] == 0){
	        c- >p_data- >array[i] = tmp;
	        break;
	    }
	}
	#endif
}

圖片

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7614

    瀏覽量

    137745
收藏 人收藏

    評論

    相關推薦

    C語言遞歸的運行順序

    今天分享一下C語言課會講到了一道非常經典的遞歸題目!
    發表于 09-07 11:43 ?932次閱讀

    【Linux+C語言真的了解system接口的調用嗎?

    【Linux + C語言】話說,真的了解system接口的調用嗎?
    的頭像 發表于 09-12 16:33 ?4311次閱讀
    【Linux+<b class='flag-5'>C</b><b class='flag-5'>語言</b>】<b class='flag-5'>你</b><b class='flag-5'>真的</b>了解system接口的調用嗎?

    真的都懂C語言

    發展前景的技術。1.嵌入式開發作為新人,第一C語言,有很多人自認為自己C語言很厲害,但是實際上一個從事嵌入式開發的老人,至少需要3-5年
    發表于 12-21 08:23

    真的Word嗎

    在日常辦公當中, Word文檔就是我們最常用的軟件之一。用它我們寫論文、寫方案、寫小說等等。但是,真的Word嗎?其實,Word軟件背后,還有一大批隱藏技能不知道。掌握他們,
    發表于 01-12 08:22

    C語言教程之遞歸解決年齡問題

    C語言教程之遞歸解決年齡問題,很好的C語言資料,快來學習吧。
    發表于 04-25 15:49 ?0次下載

    C語言教程之遞歸解決分魚問題

    C語言教程之遞歸解決分魚問題,很好的C語言資料,快來學習吧。
    發表于 04-25 15:49 ?0次下載

    Python爬蟲 真的會寫爬蟲嗎?

    以為真的會寫爬蟲了嗎?快來看看真正的爬蟲架構!
    的頭像 發表于 05-02 17:02 ?3958次閱讀
    Python爬蟲 <b class='flag-5'>你</b><b class='flag-5'>真的</b>會寫爬蟲嗎?

    “互聯網+”真的過時了嗎

    “互聯網+”真的過時了嗎
    的頭像 發表于 05-24 16:42 ?5986次閱讀

    阻抗的概念,真的了嗎

    阻抗的概念,真的了嗎
    的頭像 發表于 07-02 11:40 ?1.6w次閱讀

    真的CPU大小端模式嗎?

    真的CPU大小端模式嗎?
    的頭像 發表于 02-27 16:46 ?2797次閱讀

    是時候退休C語言了嗎

    TIOBE Programming Index 評為世界上最流行的兩種編程語言之一(參見圖 1)。它是嵌入式系統開發人員最流行的語言,用于近 80% 的嵌入式項目。經過近半個世紀的使用,嵌入式開發人員是時候轉向更現代的語言
    的頭像 發表于 07-14 08:17 ?608次閱讀
    是時候退休<b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>了嗎</b>?

    C語言-內聯函數、遞歸函數、指針函數

    這篇文章介紹C語言的內聯函數、遞歸函數、函數指針、指針函數、局部地址、const關鍵字、extern關鍵字等知識點;這些知識點在實際項目開發中非常常用,非常重要。
    的頭像 發表于 08-14 10:03 ?1733次閱讀

    精通STM32的含金量嗎?

    精通ARM的含金量嗎?精通STM32的含金量嗎?不管懂不懂都要,趕緊學。
    的頭像 發表于 04-19 09:13 ?1966次閱讀

    肖特基二極管,真的用對了嗎

    肖特基二極管,真的用對了嗎
    的頭像 發表于 12-07 14:27 ?630次閱讀
    肖特基二極管,<b class='flag-5'>你</b><b class='flag-5'>真的</b>用對<b class='flag-5'>了嗎</b>?

    關于C語言中的遞歸

    遞歸指的是在函數的定義中使用函數自身的方法。
    發表于 02-26 10:34 ?435次閱讀
    關于<b class='flag-5'>C</b><b class='flag-5'>語言</b>中的<b class='flag-5'>遞歸</b>
    主站蜘蛛池模板: 狠狠操狠狠搞 | 国产福利午夜 | 午夜美女写真福利写视频 | 成人三级在线观看 | 天天爽夜夜爽夜夜爽精品视频 | 三级视频中文字幕 | 亚洲成人资源 | 97人洗澡人人澡人人爽 | 国产va免费精品高清在线观看 | 四虎三级 | 天天插狠狠干 | 巨乳色网址 | 成人精品久久 | 久久国产精品系列 | 操片免费| 色99色| 人人天天爱天天做天天摸 | 色偷偷91综合久久噜噜 | 亚洲成人精品在线 | 国产handjob手交在线播放 | 美女全黄网站免费观看 | 五月天婷婷精品视频 | 亚洲免费国产 | 日韩精品网址 | 黄色片免费看视频 | 一级不卡毛片免费 | 亚洲国产精品第一页 | 欧美午夜剧场 | 久久亚洲综合中文字幕 | 日韩基地1024首页 | yy4080一级毛片免费观看 | 午夜一级成人 | 亚洲精品美女 | 西西人体www303sw大胆高清 | 久热国产精品视频 | 色综合久 | 日本黄色片免费看 | 国产色窝 | 久久澡| 二十年等一人小说在线观看 | 日日艹|