在链表中查找值的递归方法

时间:2017-04-17 22:57:25

标签: c++ recursion linked-list find singly-linked-list

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循环的方法转换为执行相同操作但使用递归的方法?

3 个答案:

答案 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
   }