如何使用递归返回单链表中的第n个最后一个元素
How to return the nth last element in a singly linked list using recursion?
所以我有这个递归解决方案来打印列表末尾的第n个元素:
void print_nth_from_last_rec(Node* node, int n) {
static int count { 0 };
if (!node) return;
print_nth_from_last_rec(node->next, n);
if (++count == n)
cout << node->data;
}
但是我不知道如何使用递归来返回那个元素。有可能吗?
尝试次数:
如果我有一个静态
Node*
,当(++count == n)
:Node* get_nth_from_last_rec(Node* node, int n) { static int count { 0 }; static Node* ret{ nullptr }; if (node) { get_nth_from_last_rec(node->next, n); if (++count == n) ret = node; } return ret; }
也可以将引用传递给
out
节点,并将第n个元素分配给它
但是有更好的方法吗?这些静态在我看来不太干净。
Node* get_nth_from_last_rec(Node* node, int& n)
{
if (node)
{
Node* result = get_nth_from_last_rec(node->next, n);
if (result)
return result;
else if (! n--)
return node;
}
return nullptr;
}
以下是我的操作方法(我希望advance
的作用从上下文中显而易见):
Node* get_nth_from_last(Node* node, int n, Node *ahead = 0) {
if (ahead == 0) {
// might like to check for size < n at the same time
// and return something to indicate error in that case
ahead = advance(node, n);
}
if (ahead->next == 0) return node; // or whatever the end condition is
return get_nth_from_last(node->next, n, ahead->next);
}
如果要将默认参数隐藏在调用程序之外,请使用helper函数。无论如何,它只是为了提高效率,如果你想要非常慢的代码,那么就不用它,在每个递归步骤调用advance
。
您几乎不应该仅仅为了使递归工作而需要static
变量。您总是可以添加具有默认值的参数,或者编写具有额外参数的辅助函数并调用它来完成所有工作。除了它们可能给读取器带来的任何混乱之外,它们还使函数成为非线程安全的,并且不能从信号处理程序中重新进入。
我的代码执行2 * len - n
节点前进,而您的代码只执行len
(加上递归返回的n
工作)。如果你想坚持你的性能特征,但牺牲尾部递归,那么像这样的东西(我要么在这方面落后一个,要么在我的第一个答案上落后,这取决于n
的含义…):
Node* get_nth_from_last_helper(Node* node, int &depth) {
if (node == 0) return 0;
Node *n = get_nth_from_last_helper(node->next, depth);
--depth;
return (depth == 0) ? node : n;
}
Node *get_nth_from_last(Node *node, int n) {
return get_nth_from_last_helper(Node *node, n);
}
就我个人而言,我会使用从前面开始的第n个函数倒数到0
Node* get_nth_from_first_rec(Node* node, int n) {
if (!node || n == 0) {
return node;
}
return get_nth_from_last_rec(node->next, n - 1);
}
并计算列表中元素的数量(如果需要,可以递归)
int get_list_length(Node* node) {
if (!node) {
return 0;
}
return 1 + get_list_length(node->next);
}
因此,我可以将索引计算为第一个索引的第n个
Node* get_nth_from_last_rec(Node* node, int n) {
int count = get_list_length(node);
return get_nth_from_first_rec(node, n - count);
}
在这里,我相信我有一种在Java中解决它的简洁的尾部递归方法。
public static LinkedListNode findnthToLastRecursionHelper(LinkedListNode node, LinkedListNode last,int pos){
if(node==null) return null;
if(pos<1)
{
pos=1; //We have reached the nth iteration for last, now time to increment node and last together.
node = node.next;
if(last==null) return node;
}
else if(last==null) return null;
return findnthToLastRecursionHelper(node,last.next,--pos);
}
这是负责将last
指针移动到nth
位置的主要尾部递归块,并且一旦到达位置,就移动node
&last
指针在一起。
public static LinkedListNode findnthToLastRecursion(LinkedListNode head,int pos){
return findnthToLastRecursionHelper(head,head.next,pos);
}
这是为了保持美观而调用的函数。
相关文章:
- lower_bound()返回最后一个元素
- 使用运算符 [] 引用 std::vector 上最后一个元素时出现问题<>
- Lower_bound不适用于具有 3 个元素的向量的最后一个元素
- 查找数组中第一个最小值和最后一个最大值元素之间的算术平均值
- 仅显示链表的最后一个元素
- push_back通过自行创建的对象获取最后一个元素的向量
- 使用 map.end() 访问 map 的最后一个元素
- 如何知道地图中的最后一个元素是否被删除?
- std::矢量保存 只推送最后一个元素
- 反转后不返回最后一个元素
- 如何在新数组较小时创建新数组并将旧数组的最后一个元素复制到新数组中?
- 在 QListView 中显示最后一个元素
- C++:在进行切片时对迭代器的约定,特别是对于访问最后一个元素并最终将其删除
- 遍历列表包含排除最后一个元素的内容
- 如何打印第一个和最后一个元素的和,然后打印第二个和倒数第二个元素的总和,依此类推
- C++链表最后一个元素的迭代器?
- 这种获取模板参数包中最后一个元素的方法是否有隐藏的开销?
- 使用 STL 交换堆栈 C++ 中的第一个和最后一个元素
- 查找数组的第一个和最后一个索引,其中 from 和 to 元素的顺序总和最大
- 数组:如何在指定索引之前显示数组的第一个和最后一个元素以及数组元素的差异?