template<class Type>
int StringList<Type>::find(Type value)
{
int count = 0;
// Start of linked list
Node<Type> *current = head;
// Traverse list until end (NULL)
while (current != NULL)
{
// Increase counter if found
if (current->data == value)
{
count++;
}
// If not, move to the next node
current = current->next;
}
cout << value << " was found " << count << " times" << endl;
return 0;
// same function but using Recursive method
// Start of linked list
Node<Type> *current = head;
int count = 0;
// Thinking this is the base case, since its similar to the while loop
if (current == NULL)
{
return 0;
}
// same as the while loop, finding the value increase the count, or in this case just prints to console
if ((current->data == value))
{
cout << "Found match" << endl;
return 0;
}
else
{ // If it didnt find a match, move the list forward and call the function again
current = current->next;
return find(value);
}
}
该函数应该找到搜索到的值并返回链接列表中某个值的次数。
如何将第一个使用while循环的方法转换为执行相同操作但使用递归的方法?
答案 0 :(得分:0)
为了使用递归,您需要更改find函数的签名(或添加具有不同签名的新函数)以将节点指针作为参数:
template<class Type>
int StringList<Type>::find(Type value, Node<Type> *where)
{
if (where != nullptr)
{
// Do things
}
}
然后,当您遍历列表时,将where->next
传递给该函数。一旦您点击列表的末尾,使用nullptr
值,堆栈就会展开。
递归的一个关键方面,因为正在使用的函数或方法只需要处理容器的单个节点。然后它会调用自己与要处理的下一个节点,直到没有更多节点。为了使这项工作,该功能需要节点作为参数进行处理,这是您当前代码遇到问题的地方。
请记住,递归的优雅和简洁不是免费的。方法对自身进行的每次调用都会占用堆栈,因此如果进程的堆栈耗尽,足够大的容器可能会导致崩溃。
答案 1 :(得分:0)
对于初学者而不是返回类型int
,最好使用无符号类型,例如size_t
您可以使用以下方法。定义两种方法。第一个是公共非静态方法find
,定义为
template<class Type>
size_t StringList<Type>::find( const Type &value ) const
{
return find( head, value );
}
第二个是私有静态方法,其中两个参数定义为
template<class Type>
static size_t StringList<Type>::find( Node<Type> *current, const Type &value )
{
return current == nullptr ? 0 : ( current->data == value ) + find( current->next, value );
}
答案 2 :(得分:0)
如何将第一个使用while循环的方法转换为 什么东西做同样的事情,但使用递归?
以下内容将更接近您的需求。你真的应该提供一个[MCVE] ......缺乏对你的代码的许多猜测和假设。
// It looks like StringList is a class (I ignored template issues),
// and it appears that your class holds 'anchors' such as head
// StringList is probably the public interface.
//
// To find and count a targetValue, the code starts
// at the head node, and recurses through the node list.
// I would make the following a public method.
//
int StringList::findAndCountTargetValue(int targetValue)
{
int retVal = 0;
if (nullptr != head) // exists elements to search?
retVal = head->countTV(targetValue); // recurse the nodes
// else no match is possible
return(retVal);
}
// visit each node in the list
int Node::countTV(const int targetValue)
{
int retVal = 0; // init the count
if (data != targetValue) // no match
{
if(nullptr != next) // more elements?
retVal += next->countTV() // continue recursive count
}
else
{
std::cout << "Found match" << std::endl; // for diag only
retVal += 1; // because 1 match has been found
if(nullptr != next) // more elments
retVal += next->countTV(); // continue recursive count
}
return (retVal); // always return value from each level
}