【问题标题】:How to find the previous node of a singly linked list without the head pointer如何在没有头指针的情况下找到单链表的前一个节点
【发布时间】:2018-07-25 18:42:23
【问题描述】:

您好,这是一个面试问题,任何建议/答案将不胜感激。

在问题中:他给了我一个单链表,并指出了一个随机节点,并要求我找到上一个节点。我问我是否可以访问头指针,他说没有。我问是循环链表还是双链表,他又说不是。如何找到上一个节点?

附: - 我根本无法访问头指针,所以我无法跟踪前一个指针。

【问题讨论】:

  • 你确定这里的链表类型吗?可能是异或链表。
  • 是的,我确定这是一个普通的链表,他特别说
  • 我知道这不是一个真正的答案,但我认为在这种情况下您无法找到上一个项目。 :)
  • @CanBayar 是的,我也这么认为。当我问面试官时,他说“考虑一下”,然后继续下一个问题
  • 如果您拥有的唯一信息是该节点是单链表的一部分,那么您找不到父节点。如果没有头指针,或者对您知道在列表中位于该节点之前的节点的引用,那么就不可能找到父节点。听听面试官对这个问题的解决方案会很有趣。

标签: data-structures linked-list nodes


【解决方案1】:

从纯粹的 CS 角度来看,如果你构造一个长度为 n 的非循环单链表:

L1 -> L2 -> ... -> L(x-1) -> Lx -> ... -> Ln

以下定理成立:

定理:节点Lx只能由节点L1到Lx到达。

只要看一眼,就很明显:没有退路。我跳过了一些步骤,但这是一个相当容易得出的结论。没有从Lx 到链中先前节点的路径。正式的证明将使用归纳法。 This page explains 如何对链表进行归纳。

反义词是:节点Lx 无法访问节点L1 到L(x-1)。作为直接结果L(x-1) 无法通过节点Lx 到达,这与采访者的说法相矛盾。 要么面试官错了,要么你对面试官的解读有误。

我只得到了随机节点,我被要求找到前一个节点,没有头指针,没有循环

如果这样的事情成为可能,它将破坏计算机科学的许多现有应用。例如,Python 或 Ruby 等安全语言中的 垃圾收集 依赖于一旦没有通往节点的路径就无法访问的节点。如果您能够以这种方式访问​​节点,则可能会导致“释放后使用”错误,从而使语言不安全。

面试官可能希望你说这个问题是不可能的。在这种情况下,我接受过采访。有时,面试官正在探索一个更有“创造性”的解决方案。例如,在像 C++ 这样的语言中,所有节点都可能存储在底层资源池中,可以迭代该资源池以找到前一个节点。但是,在面试和实践中,我会发现这种实现方式不同寻常。

不用说,你所说的问题在给定的限制下是不可能的。

【讨论】:

    【解决方案2】:

    你可以这样做..你可以用下一个节点的值替换当前节点的值..并且在第二个最后一个节点的下一个你可以放空。就像从字符串中删除一个元素一样。 这是代码

        void deleteNode(ListNode* node) {
            ListNode *pre=node;
           while(node->next) 
            {
                node->val=node->next->val;
                pre=node;
                node=node->next;
            }
            pre->next=NULL;
        
    }
    

    【讨论】:

      【解决方案3】:

      您可以这样做的唯一方法是链表是循环的,即最后一个节点作为循环列表类型指向第一个节点。然后它只是一个列表遍历,跟踪前一个节点,直到你再次到达你所在的节点。

      【讨论】:

        【解决方案4】:

        这是可能的。这是供您参考的代码。在这里,我假设我知道每个节点的数据值。您可以通过在调用方法中提供“b”和“c”来测试此代码。显然你也可以创建多个对象。让我知道这是否是您正在寻找的解决方案。

        #删除单链表中任意一个节点的程序

        class A:
            def __init__(self,data):
                self.data=data
                self.node=None
        
        class B:
            def __init__(self):
                self.head=None
        
            def printlist(self):
                printval=self.head
                c=0
                self.call(printval,c)
        
            def call(self,printval,c):
                temp1=None
                temp2=None
                while printval:
                    if printval.data=='c' and c==0:
                        c=c+1
                        temp2=printval.node
                        del printval
                        temp1.node=temp2
                        printval=temp1.node
                    print(printval.data)
                    temp1 = printval
                    printval=printval.node
        
        
        o1=B()
        o1.head=A("a")
        o2=A("b")
        o3=A("c")
        o4=A("d")
        o1.head.node=o2
        o2.node=o3
        o3.node=o4
        o1.printlist()
        

        【讨论】:

        • 另外,顺便提一下,这段代码只会删除第一个和最后一个数据值之间的项目。如果您尝试删除第一个值,那么它将抛出错误,因为它没有任何父节点,如果您尝试删除最后一个值,那么它将被删除但会抛出异常,因为它没有任何子节点并且我没有在我的代码中处理这些条件。
        猜你喜欢
        • 2021-06-02
        • 1970-01-01
        • 2018-03-24
        • 2011-11-04
        • 1970-01-01
        • 2011-06-10
        • 1970-01-01
        • 2011-12-14
        • 2021-11-19
        相关资源
        最近更新 更多