C言語の再帰は本当に分かりましたか?
再帰とは何か?
再帰といえば、スタックを言わないと、再帰の特徴は同じ関数を呼び続けていることです。この関数に再帰限界がないと、デッドサイクルになります。再帰を検討するには再帰の限界を検討しなければならないです。
例を見ます。
このプロセスは、つまり、スタックを渡すプロセスといいます。
全部で何回再帰ができますか?
上で述べましたが、再帰的にスタックを使用した以上、システムのスタックのサイズには限界があります。無限のスタックの大きさをシステムに割り当てることはできません。
やはり上の例です。着信データを大きく設定して実行してみます。
だから再帰回数はきっと限定されています。
再帰的に階乗を求める
再帰的に階乗を求めるのは古典的な方法です。コードを見てみます。
コードだけを見ても言いにくいです。私達は写真を見て彼の呼び出しを見にきました。もし私達が要求しているのは5階の乗車です。
再帰とハノータ
ハノータ問題はインドの古い伝説に由来する益智玩具です。サンスクリットは世界を創造する時にダイヤモンドの柱を三本作りました。柱の上で下から上に行くと大きさ順に64枚の黄金の円盤を積み重ねています。サンスクリットは、円盤を下から大きさ順に別の柱に並べ直すようボロブモンに命じました。また、小さな円盤では円盤を拡大することができず、3本の柱の間では一回に1つの円盤しか移動できないと規定されています。
このようなハノータなら、一人一人が簡単だと思います。三歩で移動が完了します。
1、小円盤を三本目の柱に置く
2、中円盤を二本目の柱に置く
3、小円盤を二本目の柱に置く
4、大きな円盤を三本目の柱に置く
5、小さな円盤を最初の柱に置く
6、中円盤を第三の柱に置く
7、小皿を三本目の柱に置く
図に示すように
私達の上を分析するのは細分的な方法で、移動の核心の思想は3歩に分けます。
1、最初の柱のn-1円盤を二番目の柱に移動します。
2、最初の柱のn番目の円盤を3番目の柱に移動します。
3、二番目の柱のn-1個の円盤を三番目の柱に移動します。
だから再帰的に現れました。
1、最初の柱のn-1円盤を第二の柱に移動させる「再帰実現」。
2、最初の柱のn番目の円盤を3番目の柱に移動します。
3、第二の柱のn-1個の円盤を第三の柱に移動させる「再帰実現」。
C言語コードの実現
強化版の修正
ソフトウェアの書き方を強化しました。コードをよく見てください。書いたのはちょっと速すぎて、詳しく考えていません。後で完璧になります。
ここでC言語の再帰的な文章について紹介します。C言語の再帰的な内容は以前の文章を検索したり、下記の関連記事を引き続き閲覧してください。これからもよろしくお願いします。
再帰といえば、スタックを言わないと、再帰の特徴は同じ関数を呼び続けていることです。この関数に再帰限界がないと、デッドサイクルになります。再帰を検討するには再帰の限界を検討しなければならないです。
例を見ます。
#include "stdio.h"
int digui(unsigned long count )
{
if(count > 0){
count --;
printf("%d
",count);
digui(count);
}
return 1;
}
int main()
{
digui(10);
return (100);
}
この再帰関数の限定判読は
if(count > 0){
彼の呼び出し順序はこの図で説明できます。このプロセスは、つまり、スタックを渡すプロセスといいます。
if(count > 0){
成功しないと判断したら、スタックから出ます。下図のように全部で何回再帰ができますか?
上で述べましたが、再帰的にスタックを使用した以上、システムのスタックのサイズには限界があります。無限のスタックの大きさをシステムに割り当てることはできません。
やはり上の例です。着信データを大きく設定して実行してみます。
#include "stdio.h"
int tigui(unsigned long count )
{
if(count > 0){
count --;
printf("%d
",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
",x);
return (0);
}
int fact(unsigned long n){//
if(n==1) return 1;// 1, 1
else return n*fact(n-1);//
}
実行結果コードだけを見ても言いにくいです。私達は写真を見て彼の呼び出しを見にきました。もし私達が要求しているのは5階の乗車です。
再帰とハノータ
ハノータ問題はインドの古い伝説に由来する益智玩具です。サンスクリットは世界を創造する時にダイヤモンドの柱を三本作りました。柱の上で下から上に行くと大きさ順に64枚の黄金の円盤を積み重ねています。サンスクリットは、円盤を下から大きさ順に別の柱に並べ直すようボロブモンに命じました。また、小さな円盤では円盤を拡大することができず、3本の柱の間では一回に1つの円盤しか移動できないと規定されています。
このようなハノータなら、一人一人が簡単だと思います。三歩で移動が完了します。
1、小円盤を三本目の柱に置く
2、中円盤を二本目の柱に置く
3、小円盤を二本目の柱に置く
4、大きな円盤を三本目の柱に置く
5、小さな円盤を最初の柱に置く
6、中円盤を第三の柱に置く
7、小皿を三本目の柱に置く
図に示すように
私達の上を分析するのは細分的な方法で、移動の核心の思想は3歩に分けます。
1、最初の柱のn-1円盤を二番目の柱に移動します。
2、最初の柱のn番目の円盤を3番目の柱に移動します。
3、二番目の柱のn-1個の円盤を三番目の柱に移動します。
だから再帰的に現れました。
1、最初の柱のn-1円盤を第二の柱に移動させる「再帰実現」。
2、最初の柱のn番目の円盤を3番目の柱に移動します。
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(" :
");
scanf(" %d",&n);
Hanoi(n, 'A', 'B', 'C');
printf("Exiting main...
");
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 !
",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("
");
}
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("------------------------
");
hannoiii(n,han_a,han_b,han_c);
printf("
");
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("------------------------
");
}
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("------------------------
");
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言語の再帰的な文章について紹介します。C言語の再帰的な内容は以前の文章を検索したり、下記の関連記事を引き続き閲覧してください。これからもよろしくお願いします。