【问题标题】:Print singly linked list in reverse order逆序打印单链表
【发布时间】:2015-01-18 18:31:38
【问题描述】:

好的,这是路易斯安那大学东南部 CMPS 280 测试中的额外问题。三行反向打印单链表。有什么想法吗?

【问题讨论】:

    标签: recursion linked-list nodes reverse iteration


    【解决方案1】:

    您的奖励问题的 C 实现,分三行:

    #include <stdio.h>
    
    struct node {
        int data;
        struct node* next;
    };
    
    void ReversePrint(struct node* head) {
        if(head == NULL) return;
        ReversePrint(head->next);
        printf("%d ", head->data);
    }
    
    int main()
    {
        struct node first;
        struct node second;
        struct node third;
    
        first.data = 1;
        second.data = 2;
        third.data = 3;
    
        first.next = &second;
        second.next = &third;
    
        ReversePrint(&first); // Should print: 3 2 1
        printf("\n");
    
        return 0;
    }
    

    【讨论】:

    • ReversePrint 的第一行应该是if head == NULL。否则,如果 head 是 NULL,你会得到一个 SEGFAULT 并且你检查 head-&gt;next 是否是 NULL
    • 顺便说一句,在尝试向它们添加数据之前,您还应该为struct nodes 初始化内存。
    • if(head == NULL) return; 可以简单地写成if (!head)return;
    • 在这里使用递归不是一个坏主意吗?因为,节点的大小可能非常大?
    【解决方案2】:

    如果允许您使用其他数据结构,请使用堆栈。

    第一步:从头节点开始遍历链表,将key放入栈中,直到到达最后一个节点。这将花费 O(n) 时间。

    第 2 步:将元素从堆栈中弹出。这将花费 O(1) 时间。

    因此,代码将是

    while(head != null){
    stack.push(head.val);
    head = head.next;
    }
    while(stack.isEmpty() != true){
    stack.pop();
    }
    

    【讨论】:

    • 第 2 步也需要 O(n)。不过好在 O(n) + O(n) 仍然只是 2O(n) == O(n)。
    【解决方案3】:

    一般来说,在 SO 上寻求帮助时,您应该始终尝试自己先解决问题。然后,如果您遇到困难,请带着您到目前为止所做的事情来到这里,并清楚地说明您的问题是什么,以最大限度地提高获得帮助的机会。

    How to ask a good question on SO

    但是,由于这是一个过去的考试问题,我的回答不会帮助你作弊:),这里是伪代码,你可以如何递归地做到这一点:

    reversePrint(head)
        if head is null then return // Line 1: base case
        reversePrint(head.next)     // Line 2: print the list after head
        print(head.data)            // Line 3: print head
    

    【讨论】:

      【解决方案4】:

      以下是执行此操作的不同方法。完整的源代码可以在下面的超链接中找到。

      1) 使用额外内存打印:https://www.geeksforgeeks.org/print-reverse-linked-list-using-stack/

      2) 使用递归打印:https://www.geeksforgeeks.org/print-reverse-of-a-linked-list-without-actually-reversing/

      3) 通过修改原始列表打印 - 即先反转列表,然后从头开始打印。

      反转列表源码:https://www.geeksforgeeks.org/reverse-a-linked-list/

      4) 打印不使用额外空间或修改原始列表:https://www.geeksforgeeks.org/print-reverse-linked-list-without-extra-space-modifications/

      5) 使用回车 (“r”) 打印 : https://www.geeksforgeeks.org/an-interesting-method-to-print-reverse-of-a-linked-list/

      【讨论】:

        【解决方案5】:

        下面是我没有堆栈的迭代 Java 解决方案。我想空间复杂度仍然是 O(n) 因为 StringBuilder 的长度随着列表中的项目数线性增长。但是,我们可以不使用堆栈(数据结构或递归调用堆栈)而摆脱困境,如果我们所做的只是将元素打印到控制台,那么这两者都不是必需的。此外,迭代堆栈解决方案使用两个循环,而这种方法只需要一个。最后,时间复杂度还是O(n),比另一个答案引用的Geeks for Geeks的二次算法要好很多。

        void printInReverse(ListNode head) {
          StringBuilder sb = new StringBuilder();
        
          ListNode n = head;
          while (n != null) {
            sb.insert(0, "<-" + n.data);
            n = n.next;
          }
        
          System.out.println(sb.toString());
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-15
          • 2012-10-25
          • 1970-01-01
          • 1970-01-01
          • 2012-04-08
          • 2016-06-22
          相关资源
          最近更新 更多