繁体   English   中英

使用递归反转链表

[英]Reverse a linked list using recursion

void reve(struct Node *head)display(struct Node *head)方法采用一个参数 - 链表的头部。 我想打印整个链表,但我的显示 function 只打印4

#include <iostream>

using namespace std;

struct Node {
    int data;
    struct Node *link;
};

void display(struct Node *head) {
    if (head == NULL) {
        return;
    }
    cout << head->data << "\t";
    display(head->link);
    //head = head->link;
}

struct Node *reve(struct Node *head) {
    struct Node *p = head;
    if (p->link == NULL) {
        head = p;
        return head;
    }
    reve(p->link);
    struct Node *temp = p->link;
    temp->link = p;
    p->link = NULL;
}

struct Node *insert(struct Node *head, int new_data) { 
    Node *new_node = new Node(); 
    new_node->data = new_data; 
    new_node->link = head; 
    head = new_node; 
    return head;
}

int main() {
    Node *head = NULL;
    head = insert(head, 1);
    head = insert(head, 2);
    head = insert(head, 3);
    head = insert(head, 4);
    cout << "The linked list is: ";
    //display(head);
    head = reve(head);
    display(head);
    return 0;
}

Output 在此处输入图像描述

如果p->link不是NULL ,则 function reve不会返回值。

由于head有超过 1 个元素,所以head = reve(head); 具有未定义的行为。

与递归相比,在简单循环中反转链表更容易实现:

struct Node *reve(struct Node *p) {
    if (p != NULL) {
        struct Node *prev = NULL;
        while (p->link) {
            struct Node *next = p->link;
            p->link = prev;
            prev = p;
            p = next;
        }
    }
    return p;
}

如果您的任务需要递归,您可以提取第一个节点,反转列表的其余部分,并将 append 作为第一个节点。 请注意,这不是尾递归,因此任何足够长的列表都可能导致堆栈溢出

struct Node *reve(struct Node *head) {
    if (head != NULL && head->link != NULL) {
        struct Node *first = head;
        struct Node *second = head->link;
        head = reve(second);
        first->link = NULL;   // unlink the first node
        second->link = first; // append the first node
    }
    return head;
}

如果你想要递归方式:

Node* reverse(Node* head) 

{ 

    if (head == NULL || head->next == NULL) 

        return head; 



    /* reverse the rest list and put  

      the first element at the end */

    Node* rest = reverse(head->next); 

    head->next->next = head;

    head->next = NULL; 

    /* fix the head pointer */

    return rest; 

} 



/* Function to print linked list */

void print() 

{ 

    struct Node* temp = head; 

    while (temp != NULL) { 

        cout << temp->data << " "; 

        temp = temp->next; 

    } 

} 

在 C++ 中,当已声明的结构或 class 用作类型说明符时,您无需使用关键字structclass

function reve具有未定义的行为。

首先head可以等于nullptr 在这种情况下,此语句

if (p->link == NULL) {

调用未定义的行为。

其次, function 在p->link不等于nullptr的情况下不返回任何内容。

    //...
    reve(p->link);
    struct Node *temp = p->link;
    temp->link = p;
    p->link = NULL;
}

这是一个演示程序,展示了如何实现这些功能。 当结构用作类型说明符时,我使用了包含关键字struct的 C 方法。

#include <iostream>

struct Node
{
    int data;
    struct Node *link;
};

struct Node * insert( struct Node *head, int data )
{
    return head = new Node{ data, head };
}

struct Node * reverse( struct Node *head )
{
    if ( head && head->link )
    {
        struct Node *tail = head;

        head = reverse( head->link );

        tail->link->link = tail;
        tail->link = nullptr;
    }

    return head;
}

std::ostream & display( struct Node *head, std::ostream &os = std::cout )
{
    if ( head )
    {
        os << head->data;
        if ( head->link )
        { 
            os << '\t';
            display( head->link, os );
        }
    }

    return os;
}

int main() 
{
    struct Node *head = nullptr;

    const int N = 10;

    for ( int i = 0; i < N; i++ )
    {
        head = insert( head, i );
    }   

    display( head ) << '\n';

    head = reverse( head );

    display( head ) << '\n';

    return 0;
}

程序 output 是

9   8   7   6   5   4   3   2   1   0
0   1   2   3   4   5   6   7   8   9

display很好。

我注意到的第一件事是您正在尝试修改复制的值。 例如第 16 行。此代码无效。

请注意,您在插入时有一个错误:您返回head而不是new_node

对于超过 1 个项目的列表,您的版本失败。 reve()应该返回原始列表的最后一个节点,而您没有这样做,因此 lastNode 不会指向反向列表的最后一个节点。 所以我的建议是你把它放在一边。

所以, reve

struct Node* reve(struct Node* head) {
    if (head->link == NULL) {
        return head;
    }

    struct Node* lastNode = reve(head->link);
    lastNode->link = head;
    head->link = NULL;

    return head;
}

main

int main() {
    Node* head = NULL;
    Node* last_node = head = insert(head, 1);
    head = insert(head, 2);
    head = insert(head, 3);
    head = insert(head, 4);
    head = reve(head);
    cout << "The linked list is: ";
    // Now, last_node is the new head
    display(last_node);
    return 0;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM