如何在C ++中递归打印链表

时间:2018-02-07 19:11:06

标签: c++ recursion linked-list

我按照Paul编程的方式在youtube上创建了这个链表。现在我想扩展它。我正在尝试学习如何做递归函数。

我得到的错误是head未在main.cpp中声明。我想知道是否有人可以解释我所遇到的问题。

代码:

main.cpp中:

#include <cstdlib>
#include <iostream>
#include "linkedlist.h"

using namespace std;

int main(int argc, char** argv)
{

    List list;
    list.addNode(1);
    list.addNode(2);
    list.addNode(3);
    list.addNode(4);
    list.addNode(5);

    cout << "Printing list" << endl;
    list.printList();

    cout << "Printing list recursively" << endl;
    list.printListRecur(head);

    return 0;

}

linkedlist.h:

#ifndef _LINKEDLISTHEADER_
#define _LINKEDLISTHEADER_

class List{
private:

    typedef struct node{
            int data;
            node* next;
    }* nodePtr;

    nodePtr head;
    nodePtr curr;
    nodePtr temp;

public:

    List();

    void addNode(int addData);
    void deleteNode(int delData);
    void printList();

    void printListRecur(nodePtr head);
    };

#endif

linkedlist.cpp:

#include <iostream>
#include <cstdlib>
#include "linkedlist.h"

using namespace std;

List::List()
{
    head = NULL;
    curr = NULL;
    temp = NULL;
}

void List::addNode(int addData)
{
    nodePtr n = new node;
    n->next = NULL;
    n->data = addData;

    if(head != NULL)
    {
            curr = head;

            while(curr->next != NULL)
            {
                    curr = curr->next;
            }

            curr->next = n;
    }
    else
    {
            head = n;
    }
}

void List::deleteNode(int delData)
{
    nodePtr delPtr = NULL;
    temp = head;
    curr = head;

    while(curr != NULL && curr->data != delData)
    {
            temp = curr;
            curr = curr->next;
    }

    if(curr == NULL)
    {
            cout << delData << " was not in the list." << endl;
            delete delPtr;
    }
    else
    {
            delPtr = curr;
            curr = curr->next;
            temp->next = curr;
            if(delPtr == head)
            {
                    head = head->next;
                    temp = NULL;
            }
            delete delPtr;

            cout << "The value " << delData << " was deleted" << endl;

    }
}

void List::printList()
{
    curr = head;

    while(curr != NULL)
    {
            cout << curr->data << endl;
            curr = curr->next;
    }
}

void List::printListRecur(nodePtr head)
{
    if(head == NULL)
    {
            return;
    }

    cout << head->data <<endl;

    printListRecur(head->next);
}   

2 个答案:

答案 0 :(得分:0)

MyView a = new MyView(this); val params = RelativeLayout.LayoutParams( ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) params.addRule(RelativeLayout.BELOW, textView3.id) params.addRule(RelativeLayout.ALIGN_PARENT_START, RelativeLayout.TRUE) relativeLayout.addView(textView, params) head类的(私有)成员。 List中没有名为head的变量,这就是编译器抱怨的原因。

我建议:

  • main()添加方法以返回List节点,然后您可以将其传递给head

    printListRecur()
  • class List { ... public: ... nodePtr getHead() { return head; } ... void printListRecur(nodePtr node); ... }; list.printListRecur(list.getHead()); 中删除输入参数,然后为printListRecur()定义一个私有方法,以递归方式调用,并将printListRecur()节点传递给它:

    head

但是,正如其他人在评论中所述,由于数据可能必须在每次迭代时被推送到调用堆栈,因此通常不需要递归地遍历列表。使用递归来迭代大型列表会遇到堆栈溢出错误,除非代码以允许编译器应用尾调用优化的方式编写,以避免堆栈错误。

在这个例子中,最好只使用一个简单的迭代循环,就像你的class List { private: ... void internalPrintListRecur(nodePtr node); ... public: ... void printListRecur(); ... }; void List::internalPrintListRecur(nodePtr node) { if (node) { cout << node->data <<endl; internalPrintListRecur(node->next); } } void List::printListRecur() { internalPrintListRecur(head); } 已经在使用一样。不要使用递归。

答案 1 :(得分:0)

要使用递归,您需要将传递和返回的数据设置为相同类型,即函数应使用Node然后返回Node,将不会形成递归调用如果函数使用List但返回Node

根据我的理解,List可以是Node的包装类。给你一个非常简单的例子:

class List {
    struct Node {
        int data; 
        Node *next;

        void print();
        ...
    };

    Node *head;

public:
    void print();
    ...
};

void List::Node::print() {
    std::cout << data << endl;
    if (next) next->print();
}

void List::print() {
    if (head) head->print();
}

List将拥有客户端可能需要的所有接口方法,但实际工作是通过Node的方法完成的,如果你想采用递归方式(因为递归消耗了更多的内存空间,因此更频繁地使用迭代)。