C++ 使用递归计算双链表中的偶数元素

C++ 使用递归计算双链表中的偶数元素,c++,recursion,data-structures,doubly-linked-list,C++,Recursion,Data Structures,Doubly Linked List,我有两个函数,一个是NumsEven(),另一个是NumsEven helper(Node*ptr)我有一个带有{2,4,5,10}的列表,我应该使用递归来计算偶数这是我到目前为止所拥有的: template <typename Data_t> Data_t DLinkedList<Data_t>::NumEven() { Node* ptr = _head; return NumEvenHelper(ptr); } template <typena

我有两个函数,一个是NumsEven(),另一个是NumsEven helper(Node*ptr)我有一个带有{2,4,5,10}的列表,我应该使用递归来计算偶数这是我到目前为止所拥有的:

template <typename Data_t>
Data_t DLinkedList<Data_t>::NumEven() {
    Node* ptr = _head;
    return NumEvenHelper(ptr);
}
template <typename Data_t>
Data_t DLinkedList<Data_t>::NumEvenHelper(Node* ptr) {
    
    ptr = _head;
    
    if (empty()) return 0;
    
    else if ((ptr->_data % 2 == 0))
        return 1 + NumEvenHelper(ptr->_next);
    
}
模板
数据链接列表::NumEven(){
节点*ptr=_头;
返回NumEvenHelper(ptr);
}
模板
数据链接列表::numevenheloper(节点*ptr){
ptr=_头;
if(empty())返回0;
否则如果((ptr->_数据%2==0))
返回1+numevenheloper(ptr->\u下一步);
}

为了解决此问题,您可以添加两个成员函数:第一个是公共函数,另一个是私有函数:

公共:
std::size\u t countEven()常量noexcept;
私人:
std::size\u t count偶数(Node*Node)const noexcept;
第一个成员函数将由双链表的用户使用,而第二个成员函数将用于实际的递归/计算

std::size\t countEven()常量noexcept{
返回偶数(_头);
}
std::size\u t count偶数(Node*Node)const noexcept{
if(nullptr!=节点){
如果(当前数据%2==0){
返回countEven(node->next)+1;//因为_数据是偶数,所以增加1
}否则{
返回countEven(node->next);//因为_数据不是偶数,所以不要递增
}
}否则{
返回0;//如果我们到达列表的末尾,我们需要返回开始值进行计数
}
}
当然,这意味着
\u data
成员是整数。

实际上有两个问题。。。通过简单的调试,很容易发现这两个问题

第一个问题是您没有理由处理列表中的奇数数据值

如果
ptr->\u data
为奇数,则
numevenheloper
函数将在不返回任何内容的情况下结束。这将导致未定义的行为,因为程序假定函数将返回有效值

该函数还将停止对奇数值的递归,因此即使列表中稍后有偶数值,也不会计算这些值

简单的解决方案是简单地添加一个
else
案例,您只需执行递归调用,而不添加
1

if (empty())
    return 0;
else if ((ptr->_data % 2 == 0))
    return 1 + NumEvenHelper(ptr->_next);
else  // Is odd
    return NumEvenHelper(ptr->_next);

第二个问题是,helper函数总是将
ptr
设置为指向
\u head
,而忽略传递的参数

这将导致非空列表上的无限递归,因为递归调用实际上是:

NumEvenHelper(_head->_next);
您不应该在helper函数中具有该赋值


现在,我们来看一个小“技巧”(这将使您的代码更难阅读和理解),这样您就不必使用
if
,也不必费心于
else
:布尔结果(如比较结果)可以隐式转换为
int
值,使用
1
表示
true
0
表示
false

这意味着您可以使用布尔条件作为部分或算术计算来代替
1
0

例如:

if (empty())
    return 0;

// No else here

return (ptr->_data % 2 == 0) + NumEvenHelper(ptr->_next);

如果该值为偶数,则会将
1
添加到递归调用的结果中,否则将添加
0

显示的代码有什么问题?请花一些时间刷新、读取SO、read以及。作为有关您的问题的提示(一些调试应该可以帮助您找到的东西):如果节点具有奇数值,会发生什么情况?在一个不相关的注释中,我假设
Data\t
是包含的数据的类型?为什么函数返回它?如果
数据\u t
不是整数类型,会发生什么情况?函数返回一个
无符号int
,这不是更有意义吗?“我应该使用递归来计算偶数”,所以不使用递归也不成问题?你有密码吗?