【问题标题】:Not able to change state of a local variable in other function using pointer to that variable无法使用指向该变量的指针更改其他函数中局部变量的状态
【发布时间】:2016-01-25 11:25:49
【问题描述】:

我写了一个方法来合并两个排序的链表(LL 是升序的)。通过使用双指针,我将头指针的地址从调用函数(main)传递给被调用函数(mergeSortedLL)。

//definition of listNode
    struct ListNode{
    int data;
    struct ListNode *next;
    };


void mergeSortedLL(struct ListNode **headA,struct ListNode *prevA,struct ListNode **headB,struct ListNode *prevB)
{
    struct ListNode *currA=*headA,*currB=*headB;
    static struct ListNode *finalHead=NULL;


//  Base Condition
if(!currA || !currB)
{

    *headA=finalHead;                     // this should change head in main function
      printList(*headA);                  // LINE-1  this function prints data of linked list sequentially. 
    return;
}

    struct ListNode *nextA=currA->next, *nextB=currB->next;

    if(currA->data>currB->data)
    {
        if(!finalHead)
            finalHead=currB;           // finalhead points to head of that LL which starts with smaller value node

        currB->next=currA;
        if(prevB)
            prevB->next=currB;
        mergeSortedLL(&currA,currB,&nextB,currB);
    }

    else
    {
        if(!finalHead)
            finalHead=currA;           //finalhead points to head of that LL which starts with smaller value node

        currA->next=currB;
        if(prevA)
            prevA->next=currA;
        mergeSortedLL(&nextA,currA,&currB,currA);
    }
}

在主函数中我创建了两个 LL
head==> -1->3->5->6->8->9                              第一个节点是 -1
head2==> 0->1->4->5->7->8->9
并在从 main 调用之后

mergeSortedLL(&head,NULL,&head2,NULL);
printList(head);                             //Line-2

我无法预测的是,mergeSortedLL 函数的第 1 行总是打印所需的排序 LL,而 main 中第 2 行的 printList 方法有时需要传递 head,有时需要传递 head2 以获得所需的输出 (0113455678899)。
例如,如果第一个 LL 更改为 head==> 1->3->5->6->8->9,(第一个节点为正 1)第 2 行需要传递 head2 而不是 head 以获得所需的 o/p。
它是如何通过双指针 headA 在 mergeSoretedLL 方法中发生的,我将(主函数的)头更改为指向 finalHead。

我认为 headA 和 headB 的值不知何故被交换了,但我在这里看不到它。 有人请解释一下。

【问题讨论】:

  • 如果没有调试器 IMO 很难弄清楚
  • 你在这里使用递归是为了自己的目的(即学习)吗?否则我会建议在这里使用迭代。它更容易实现和理解(即更不容易出错),性能更高,节省(堆栈)内存空间。
  • 是的,我也知道其他看起来并不复杂的解决方案。但我担心的是,当第 1 行给出正确的结果而 headA 持有 head 的引用(从 main 传递)时,为什么 main 中的第 2 行没有给出相同的结果。
  • 确保在第一个递归级别中,将 headA 分配给预期节点的地址。看我的回答

标签: c pointers recursion linked-list


【解决方案1】:

你需要分配:

*headA=finalHead; 

在 if 和 else 语句中也是如此。即如下:

if(!finalHead) {  // in if case
    finalHead=currB; 
    *headA = finalHead;
}

...
...

if(!finalHead) {  // in else case
    finalHead=currA; 
    *headA = finalHead;
}

这是因为当你从 main 调用时,currA 和 CurrB 不为 NULL,因为 *headA 和 *headB 不为 NULL。因此,您的代码输入基于 currA->data > currB->data 的 if 或 else 语句是否为真。在这里,您将 finalHead 分配给 currA 或 currB,但是,这并没有反映在 *headA(main 中的 head)中。所以,很明显,当你从 main 打印时,你不会得到结果。

因此,请确保在第一个递归级别中,将 headA 分配给预期节点的地址。

【讨论】:

  • 感谢您提供解决方案。现在它工作正常,但我仍然不明白这个修改是如何使代码工作的。为什么在基本条件下分配 *headA=finalHead 在这里不起作用?你能澄清一下吗
  • 哦,我知道了。每次递归中,headA 都会发生变化,这就是它不起作用的原因。对吗?
  • 没有。在基本情况下,您没有为 *headA 赋值。这是因为 currA 和 currB 不为 NULL。因此它从未将 *headA 分配给第一级递归。另外,如果它解决了问题,请接受答案。
  • 在第一级递归,即从main调用时,不进入基本条件。所以, *headA 没有改变。您正确地更改了 if 和 else 中 finalHead 的值,但这并未分配给 *headA 进行 1 次递归。希望现在很清楚。
  • 但是 if(!finalHead) 只执行了 1 次,并且最后在基本条件运行时 *headA 被分配了之前选择的 finalHead。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-10-13
  • 2010-12-13
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多