递归查找列表中的最小偶数
Find the minimum even number in a list recursively
我写过这个函数:
struct nodo * MinimoPariListaRic(struct nodo * top) {
struct nodo * minimo_p = NULL; //this should be the minimum even number
//list have one or no one element
if(top) {
if(!top->next)
if(top->valore % 2 == 0) return top; // valore(italian) = value
else return NULL;
}
else return NULL;
if(top->next)
minimo_p = MinimoPariListaRic(top->next);
if (top->valore % 2 == 0)
{
if(minimo_p->valore < top->valore) return minimo_p;
else return top;
}
else return minimo_p;
}
如果列表的元素都是偶数,函数会return取最小值,就可以了。
但如果出现奇数,则该功能无法正常工作。
如果所有数字都是奇数,函数应该 return NULL.
你的算法是错误的,如果递归调用 return NULL 因为将 minimo_p 设置为 NULL,你可能会有未定义的行为,如果 (top->valore % 2 == 0)
,你将取消引用它,它太复杂了,你不需要递归调用,只是去抛出列表,例如:
struct nodo * MinimoPariListaRic(struct nodo * l) {
struct nodo * minimo_p = NULL; //this should be the minium even number
while (l != NULL) {
if (l->valore % 2 == 0) {
if ((minimo_p == NULL) || (l->valore < minimo_p->valore))
minimo_p = l;
}
l = l->next;
}
return minimo_p;
}
因为您编辑的主题需要递归调用,例如您可以这样做:
struct nodo * MinimoPariListaRic(struct nodo * l) {
if (l == NULL)
return NULL;
else {
struct nodo * minimo_p = MinimoPariListaRic(l->next);
return ((l->valore % 2 == 0) &&
((minimo_p == NULL) || (l->valore < minimo_p->valore)))
? l : minimo_p;
}
}
如您所见,这很简单,如果 valore 是否为奇数,我在程序中只检查一次等
使用完整程序检查:
#include <stdio.h>
#include <stdlib.h>
struct nodo {
struct nodo * next;
int valore;
};
struct nodo * MinimoPariListaRic(struct nodo * l) {
if (l == NULL)
return NULL;
else {
struct nodo * minimo_p = MinimoPariListaRic(l->next);
return ((l->valore % 2 == 0) &&
((minimo_p == NULL) || (l->valore < minimo_p->valore)))
? l : minimo_p;
}
}
int main(int argc, char ** argv)
{
/* make a list from the args */
struct nodo * l = NULL;
while (argc > 1) {
struct nodo * r = malloc(sizeof(*r));
r->next = l;
if (sscanf(argv[--argc], "%d", &r->valore) != 1) {
puts("invalid number");
return 0;
}
l = r;
}
/* show list well made */
struct nodo * ll;
for (ll = l; ll != NULL; ll = ll->next)
printf("%d ", ll->valore);
putchar('\n');
/* */
ll = MinimoPariListaRic(l);
if (ll == NULL)
puts("no even value");
else
printf("min even value is %d\n", ll->valore);
/* free resources */
while (l) {
ll = l->next;
free(l);
l = ll;
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall l.c
pi@raspberrypi:/tmp $ ./a.out 1 4 2 7 8
1 4 2 7 8
min even value is 2
pi@raspberrypi:/tmp $ ./a.out
no even value
pi@raspberrypi:/tmp $ ./a.out 3
3
no even value
pi@raspberrypi:/tmp $ ./a.out 3 3 1 5
3 3 1 5
no even value
pi@raspberrypi:/tmp $ valgrind ./a.out 3 4 5 2 0
==16881== Memcheck, a memory error detector
==16881== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16881== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==16881== Command: ./a.out 3 4 5 2 0
==16881==
3 4 5 2 0
min even value is 0
==16881==
==16881== HEAP SUMMARY:
==16881== in use at exit: 0 bytes in 0 blocks
==16881== total heap usage: 6 allocs, 6 frees, 1,064 bytes allocated
==16881==
==16881== All heap blocks were freed -- no leaks are possible
==16881==
==16881== For lists of detected and suppressed errors, rerun with: -s
==16881== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi@raspberrypi:/tmp $
因为如果列表在最后位置和[=18=包含奇数整数,则minimo_p在递归的函数returns之后可以为NULL ]任何地方至少有一个偶数.
这行是错误的:
if(minimo_p->valore < top->valore) return minimo_p;
您可以在此处添加空条件:
if(minimo_p && minimo_p->valore < top->valore) return minimo_p;
如果你必须使用递归,你应该先尝试用伪语言写下来:
- 如果当前列表只有一个元素
- -> return if even, else return null
- 如果列表有更多元素
- 获取列表剩余部分的最小值
- 如果当前元素是奇数
- return 其余最小值
- 否则如果其余为空
- return这个元素
- else 如果 rest 不为空
- return小的那个
我不会对此提出异议。如果列表很长,您的堆栈就会崩溃。
一个简单的循环会更简单,更省心:
- 初始化最小值为NULL
- 用列表初始化迭代器
- while 迭代器 != Null
- 如果迭代器偶数和最小值 == Null
- 最小=迭代器
- else if even and iterator < minimum
- 最小=迭代器
- 高级迭代器
我的五分钱。我还包含了一个递归函数,用于查找具有最大偶数的节点。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct nodo
{
int valore;
struct nodo *next;
};
int push_front( struct nodo **top, int valore )
{
struct nodo *nodo_nuovo = malloc( sizeof( struct nodo ) );
int success = nodo_nuovo != NULL;
if ( success )
{
nodo_nuovo->valore = valore;
nodo_nuovo->next = *top;
*top = nodo_nuovo;
}
return success;
}
FILE * display( struct nodo *top, FILE *fp )
{
for ( ; top != NULL; top = top->next )
{
fprintf( fp, "%d -> ", top->valore );
}
fputs( "null", fp );
return fp;
}
struct nodo * MinimoPariListaRic( struct nodo * top )
{
if ( !top )
{
return top;
}
else
{
struct nodo *minimo = MinimoPariListaRic( top->next );
if ( minimo == NULL )
{
minimo = top->valore % 2 == 0 ? top : minimo;
}
else if ( top->valore % 2 == 0 )
{
minimo = minimo->valore < top->valore ? minimo : top;
}
return minimo;
}
}
struct nodo * MassimoPariListaRic( struct nodo * top )
{
if ( !top )
{
return top;
}
else
{
struct nodo *massimo = MassimoPariListaRic( top->next );
if ( massimo == NULL )
{
massimo = top->valore % 2 == 0 ? top : massimo;
}
else if ( top->valore % 2 == 0 )
{
massimo = top->valore < massimo->valore ? massimo : top;
}
return massimo;
}
}
int main(void)
{
struct nodo *top = NULL;
enum { N = 10 };
srand( ( unsigned int )time( NULL ) );
for ( int i = 0; i < N; i++ )
{
push_front( &top, rand() % N );
}
fputc( '\n', display( top, stdout ) );
struct nodo *minimo = MinimoPariListaRic( top );
if ( minimo != NULL )
{
printf( "Minimo pari valore is %d\n", minimo->valore );
}
else
{
puts( "there is no minimo pari valore" );
}
struct nodo *massimo = MassimoPariListaRic( top );
if ( massimo != NULL )
{
printf( "Massimo pari valore is %d\n", massimo->valore );
}
else
{
puts( "there is no massimo pari valore" );
}
return 0;
}
程序输出可能看起来像
8 -> 9 -> 9 -> 9 -> 7 -> 9 -> 7 -> 3 -> 1 -> 2 -> null
Minimo pari valore is 2
Massimo pari valore is 8
至于你的函数定义那么你需要检查指针是否
minimo_p
调用返回
if(top->next)
minimo_p = MinimoPariListaRic(top->next);
在下一个 if 语句中等于 NULL
if (top->valore % 2 == 0)
{
if(minimo_p->valore < top->valore) return minimo_p;
else return top;
}
我写过这个函数:
struct nodo * MinimoPariListaRic(struct nodo * top) {
struct nodo * minimo_p = NULL; //this should be the minimum even number
//list have one or no one element
if(top) {
if(!top->next)
if(top->valore % 2 == 0) return top; // valore(italian) = value
else return NULL;
}
else return NULL;
if(top->next)
minimo_p = MinimoPariListaRic(top->next);
if (top->valore % 2 == 0)
{
if(minimo_p->valore < top->valore) return minimo_p;
else return top;
}
else return minimo_p;
}
如果列表的元素都是偶数,函数会return取最小值,就可以了。 但如果出现奇数,则该功能无法正常工作。 如果所有数字都是奇数,函数应该 return NULL.
你的算法是错误的,如果递归调用 return NULL 因为将 minimo_p 设置为 NULL,你可能会有未定义的行为,如果 (top->valore % 2 == 0)
,你将取消引用它,它太复杂了,你不需要递归调用,只是去抛出列表,例如:
struct nodo * MinimoPariListaRic(struct nodo * l) {
struct nodo * minimo_p = NULL; //this should be the minium even number
while (l != NULL) {
if (l->valore % 2 == 0) {
if ((minimo_p == NULL) || (l->valore < minimo_p->valore))
minimo_p = l;
}
l = l->next;
}
return minimo_p;
}
因为您编辑的主题需要递归调用,例如您可以这样做:
struct nodo * MinimoPariListaRic(struct nodo * l) {
if (l == NULL)
return NULL;
else {
struct nodo * minimo_p = MinimoPariListaRic(l->next);
return ((l->valore % 2 == 0) &&
((minimo_p == NULL) || (l->valore < minimo_p->valore)))
? l : minimo_p;
}
}
如您所见,这很简单,如果 valore 是否为奇数,我在程序中只检查一次等
使用完整程序检查:
#include <stdio.h>
#include <stdlib.h>
struct nodo {
struct nodo * next;
int valore;
};
struct nodo * MinimoPariListaRic(struct nodo * l) {
if (l == NULL)
return NULL;
else {
struct nodo * minimo_p = MinimoPariListaRic(l->next);
return ((l->valore % 2 == 0) &&
((minimo_p == NULL) || (l->valore < minimo_p->valore)))
? l : minimo_p;
}
}
int main(int argc, char ** argv)
{
/* make a list from the args */
struct nodo * l = NULL;
while (argc > 1) {
struct nodo * r = malloc(sizeof(*r));
r->next = l;
if (sscanf(argv[--argc], "%d", &r->valore) != 1) {
puts("invalid number");
return 0;
}
l = r;
}
/* show list well made */
struct nodo * ll;
for (ll = l; ll != NULL; ll = ll->next)
printf("%d ", ll->valore);
putchar('\n');
/* */
ll = MinimoPariListaRic(l);
if (ll == NULL)
puts("no even value");
else
printf("min even value is %d\n", ll->valore);
/* free resources */
while (l) {
ll = l->next;
free(l);
l = ll;
}
return 0;
}
编译与执行:
pi@raspberrypi:/tmp $ gcc -Wall l.c
pi@raspberrypi:/tmp $ ./a.out 1 4 2 7 8
1 4 2 7 8
min even value is 2
pi@raspberrypi:/tmp $ ./a.out
no even value
pi@raspberrypi:/tmp $ ./a.out 3
3
no even value
pi@raspberrypi:/tmp $ ./a.out 3 3 1 5
3 3 1 5
no even value
pi@raspberrypi:/tmp $ valgrind ./a.out 3 4 5 2 0
==16881== Memcheck, a memory error detector
==16881== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==16881== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==16881== Command: ./a.out 3 4 5 2 0
==16881==
3 4 5 2 0
min even value is 0
==16881==
==16881== HEAP SUMMARY:
==16881== in use at exit: 0 bytes in 0 blocks
==16881== total heap usage: 6 allocs, 6 frees, 1,064 bytes allocated
==16881==
==16881== All heap blocks were freed -- no leaks are possible
==16881==
==16881== For lists of detected and suppressed errors, rerun with: -s
==16881== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
pi@raspberrypi:/tmp $
因为如果列表在最后位置和[=18=包含奇数整数,则minimo_p在递归的函数returns之后可以为NULL ]任何地方至少有一个偶数.
这行是错误的:
if(minimo_p->valore < top->valore) return minimo_p;
您可以在此处添加空条件:
if(minimo_p && minimo_p->valore < top->valore) return minimo_p;
如果你必须使用递归,你应该先尝试用伪语言写下来:
- 如果当前列表只有一个元素
- -> return if even, else return null
- 如果列表有更多元素
- 获取列表剩余部分的最小值
- 如果当前元素是奇数
- return 其余最小值
- 否则如果其余为空
- return这个元素
- else 如果 rest 不为空
- return小的那个
我不会对此提出异议。如果列表很长,您的堆栈就会崩溃。
一个简单的循环会更简单,更省心:
- 初始化最小值为NULL
- 用列表初始化迭代器
- while 迭代器 != Null
- 如果迭代器偶数和最小值 == Null
- 最小=迭代器
- else if even and iterator < minimum
- 最小=迭代器
- 高级迭代器
- 如果迭代器偶数和最小值 == Null
我的五分钱。我还包含了一个递归函数,用于查找具有最大偶数的节点。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct nodo
{
int valore;
struct nodo *next;
};
int push_front( struct nodo **top, int valore )
{
struct nodo *nodo_nuovo = malloc( sizeof( struct nodo ) );
int success = nodo_nuovo != NULL;
if ( success )
{
nodo_nuovo->valore = valore;
nodo_nuovo->next = *top;
*top = nodo_nuovo;
}
return success;
}
FILE * display( struct nodo *top, FILE *fp )
{
for ( ; top != NULL; top = top->next )
{
fprintf( fp, "%d -> ", top->valore );
}
fputs( "null", fp );
return fp;
}
struct nodo * MinimoPariListaRic( struct nodo * top )
{
if ( !top )
{
return top;
}
else
{
struct nodo *minimo = MinimoPariListaRic( top->next );
if ( minimo == NULL )
{
minimo = top->valore % 2 == 0 ? top : minimo;
}
else if ( top->valore % 2 == 0 )
{
minimo = minimo->valore < top->valore ? minimo : top;
}
return minimo;
}
}
struct nodo * MassimoPariListaRic( struct nodo * top )
{
if ( !top )
{
return top;
}
else
{
struct nodo *massimo = MassimoPariListaRic( top->next );
if ( massimo == NULL )
{
massimo = top->valore % 2 == 0 ? top : massimo;
}
else if ( top->valore % 2 == 0 )
{
massimo = top->valore < massimo->valore ? massimo : top;
}
return massimo;
}
}
int main(void)
{
struct nodo *top = NULL;
enum { N = 10 };
srand( ( unsigned int )time( NULL ) );
for ( int i = 0; i < N; i++ )
{
push_front( &top, rand() % N );
}
fputc( '\n', display( top, stdout ) );
struct nodo *minimo = MinimoPariListaRic( top );
if ( minimo != NULL )
{
printf( "Minimo pari valore is %d\n", minimo->valore );
}
else
{
puts( "there is no minimo pari valore" );
}
struct nodo *massimo = MassimoPariListaRic( top );
if ( massimo != NULL )
{
printf( "Massimo pari valore is %d\n", massimo->valore );
}
else
{
puts( "there is no massimo pari valore" );
}
return 0;
}
程序输出可能看起来像
8 -> 9 -> 9 -> 9 -> 7 -> 9 -> 7 -> 3 -> 1 -> 2 -> null
Minimo pari valore is 2
Massimo pari valore is 8
至于你的函数定义那么你需要检查指针是否
minimo_p
调用返回
if(top->next)
minimo_p = MinimoPariListaRic(top->next);
在下一个 if 语句中等于 NULL
if (top->valore % 2 == 0)
{
if(minimo_p->valore < top->valore) return minimo_p;
else return top;
}