【问题标题】:Write a recursive algorithm to remove elements from a linked list. Write a recursive algorithm to add elements into a linked list编写递归算法从链表中删除元素。编写递归算法将元素添加到链表中
【发布时间】:2017-06-09 18:37:46
【问题描述】:

我在编写添加和删除函数时遇到了一些困难。 下面是一些用于显示列表、搜索和删除列表的代码。

我知道如何迭代地实现它,但是使用递归,我遇到了一些问题。

#include <iostream>
#include <string>

using namespace std;

struct AddressBook
{
    string name;
    string surname;
    long long phone;
    AddressBook* next;
};

void delPerson(AddressBook*& head)
{
    if (head == NULL)
    {
        cout << "There are no persons in my book\n";
    }
    else
    {
        string pName;
        cout << "Enter name of person: ";
        getline(cin, pName);
        AddressBook* temp = head;
        AddressBook* curr = NULL;
        while (temp != NULL)
        {
            if (temp->name == pName)
            {
                break;
            }
            else
            {
                curr = temp;
                temp = temp->next;
            }
        }
        if (temp == NULL)
        {
            cout << "There are no person with this name\n";
        }
        else
        {
            if (temp == head)
            {
                head = head->next;
                delete temp;
            }
            else
            {
                curr->next = temp->next;
                delete temp;
            }
            cout << pName << " was deleted from the book\n";
        }
    }
}

void display(AddressBook* head)
{
    if (head == NULL)
    {
        cout << "My book is empty\n";
    }
    else
    {
        AddressBook* temp = head;
        while (temp != NULL)
        {
            cout << endl;
            cout << "Name: " << temp->name << endl;
            cout << "Surname: " << temp->surname << endl;
            cout << "Phone: " << temp->phone << endl;
            temp = temp->next;
        }
    }
}

void search(AddressBook* head)
{
    if (head == NULL)
    {
        cout << "My book is empty\n";
    }
    else
    {
        cin.get();
        string pName;
        cout << "Enter name of person: ";
        getline(cin, pName);
        AddressBook* temp = head;
        while (temp != NULL)
        {
            if (temp->name == pName)
            {
                cout << temp->name << " is found\n\n";
                cout << "Name: " << temp->name << endl;
                cout << "Surname: " << temp->surname << endl;
                cout << "Phone: " << temp->phone << endl;
                break;
            }
            else
            {
                temp = temp->next;
            }
        }
        if (temp == NULL)
        {
            cout << pName << " isn't found in my book\n";
        }
    }
}

void delMemory(AddressBook* head)
{
    while (head != NULL)
    {
        AddressBook* temp = head;
        head = head->next;
        delete temp;
    }
}

void addPerson(AddressBook*& head)
{
    string pName;
    string sName;
    long long pPhone = 0;
    while (true)
    {
        cin.ignore();
        cout << endl;
        cout << "Enter the name(press '0' to end): ";
        getline(cin, pName);
        if (pName == "0")break;
        cout << "Enter surname: ";
        getline(cin, sName);
        cout << "Enter phone: ";
        cin >> pPhone;
        AddressBook* bleah = new AddressBook;
        bleah->name = pName;
        bleah->surname = sName;
        bleah->phone = pPhone;
        bleah->next = NULL;

        if (head == NULL)
        {
            head = bleah;
        }
        else
        {
            AddressBook* temp = head;
            while (temp->next != NULL)
            {
                temp = temp->next;
            }
            temp->next = bleah;
        }
    }
}


int main() 
{
    cout << "=============== My Address Book ===============\n\n";
    cout << "1. To add person\n";
    cout << "2. To display all\n";
    cout << "3. To delete person\n";
    cout << "4. To search person\n";
    cout << "5. Exit\n";

    AddressBook* head = NULL;
    int choice = 0;

    while (true)
    {
        cin >> choice;
        switch (choice)
        {
        case 1: addPerson(head);
            break;
        case 2: display(head);
            break;
        case 3: cin.get();
            delPerson(head);
            break;
        case 4: search(head);
            break;
        case 5: return 0;
        default: return 0;
        }
        cout << "=============== My Address Book ===============\n\n";
        cout << "1. To add person\n";
        cout << "2. To display all\n";
        cout << "3. To delete person\n";
        cout << "4. To search person\n";
        cout << "5. Exit\n";
        cout << endl;
    }
    delMemory(head);

    return 0;
}

这是递归解决方案,但我在实现添加和删除功能时遇到了麻烦

#include <iostream>
#include <string>

using namespace std;

struct AddressBook
{
    string name;
    string surname;
    long long phone;
    AddressBook* next;
};


AddressBook* delPerson(AddressBook*& head)
{

}

AddressBook* display(AddressBook* head)
{
    if (head!= NULL)
    {
        cout << endl;
        cout << "Name: " << head->name << endl;
        cout << "Surname: " << head->surname << endl;
        cout << "Phone: " << head->phone << endl;
        return display(head->next);
    }
    return head;
}

AddressBook* search(AddressBook* head, string pName)
{
    if (head == NULL)
    {
        cout << pName << " isn't found in my book\n";
        return head;
    }
    if (head->name == pName)
    {
        cout << head->name << " is found\n\n";
        cout << "Name: " << head->name << endl;
        cout << "Surname: " << head->surname << endl;
        cout << "Phone: " << head->phone << endl;
        return head;
    }
    else
    {
        return search(head->next, pName);
    }
}

void delMemory(AddressBook* head)
{
    if (head != NULL)
    {
        delMemory(head->next);
    }
    delete head;
}


AddressBook* allMem(AddressBook*& head)
{

}


int main()
{
    cout << "=============== My Address Book ===============\n\n";
    cout << "1. To add person\n";
    cout << "2. To display all\n";
    cout << "3. To delete person\n";
    cout << "4. To search person\n";
    cout << "5. Exit\n";

    AddressBook* head = NULL;
    string pName;
    int choice = 0;

    while (true)
    {
        cin >> choice;
        switch (choice)
        {
        case 1: allMem(head);
            break;
        case 2: display(head);
            break;
        case 3: cin.get();
            delPerson(head);
            break;
        case 4: cin.get();
            cout << "Enter name of person: ";
            getline(cin, pName);
            search(head, pName);
            break;
        case 5: return 0;
        default: return 0;
        }
        cout << "=============== My Address Book ===============\n\n";
        cout << "1. To add person\n";
        cout << "2. To display all\n";
        cout << "3. To delete person\n";
        cout << "4. To search person\n";
        cout << "5. Exit\n";
        cout << endl;
    }
    delMemory(head);

    return 0;
}

【问题讨论】:

  • 那些问题是?
  • 听起来像是一个家庭作业问题,首先您需要了解指针的工作原理,然后利用它们进行递归迭代。
  • delPersonaddPerson 究竟应该做什么?你说你知道如何迭代地实现它们——展示你的迭代实现,这至少可以解释它们的目的。
  • @IgorTandetnik,我认为它们是在列表中添加节点和删除节点的过程
  • 欢迎来到 StackOverflow。请阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确描述问题之前,我们无法有效地帮助您。我们应该能够将您发布的代码粘贴到文本文件中并重现您描述的问题。 StackOverflow 不是编码或教程服务。

标签: c++ algorithm recursion linked-list


【解决方案1】:

已经发布的内容遗漏了大部分问题:在递归函数中要求用户输入只会导致痛苦。在每次迭代中都要求用户输入,或者需要传递额外的控制信息来告诉函数不要要求用户输入。要么是糟糕的计划。

改为插入另一个或两个函数。从软件工程的角度来看,这是有益的:一个功能应该做最少的工作来完成一项工作。只做一件事的函数很容易理解,很容易调试,而且往往很短。

所以我们需要一个函数来从用户那里获取地址簿:

AddressBook*createAddressBook()
{
    AddressBook* bleah = new AddressBook; // terrible name, by the way
    // since we got the bleah first, we can directly assign to it. No need for
    // extra temporary variables.
    cout << "Enter the name: ";  
    getline(cin, bleah->name);
    cout << "Enter surname: ";
    getline(cin, bleah->surname);
    cout << "Enter phone: ";
    cin >> bleah->phone; // bad idea to store phone number as a number.
                         // For example a number can't record preceding zeros
    bleah->next = NULL;
    return bleah;
}

这是一个简单的愚蠢函数,除了制作地址簿之外什么也不做。老实说,这应该是一个 AddressBook 构造函数,但我们可以将其保存到以后的问题中。另请注意,在 0 废话上没有任何出口。这个函数创建一个地址簿。时期。如果你不想要一个地址簿,你不要调用这个函数。让菜单句柄退出。

接下来我们需要一个函数来查找AddressBoook 的添加位置。看起来这总是列表的末尾,所以

AddressBook*& findEnd(AddressBook *& head)
{
    if (head != NULL)
    {
        return findend(head->next); // keep looking for the end
    }
    return head; // return the end.
}

再次,一个简单而愚蠢的函数,除了查找列表中的最后一个下一个之外什么都不做。请注意,您将获得对地址簿指针的引用。这使您可以愉快地返回指向 NULL 的 next 并将 NULL 替换为新的 AddressBook

这让我们回到addPerson

AddressBook* addPerson(AddressBook*& head)
{
    findEnd(head) = createAddressBook();

    return head;
}

简单而愚蠢的函数,它调用另外两个简单而愚蠢的函数并将一个人添加到列表中。

delPerson 应用类似的过程。

注意:我没有运行任何这些。里面可能有一两个错字。

【讨论】:

  • 这非常有用!非常感谢队友!
【解决方案2】:

这是一个非常简单的示例,说明如何使用递归添加到链表。您可以将此技术应用于上面的示例。

struct node{
    int i;
    node* next;
};
void add(node* cur, int i){
       if(cur->next == nullptr){
               node* n = new node;
               n->i = i;
               cur->next = n;
       }
       else
               add(cur->next, i);
}

您只需检查下一个节点是否为空。如果是,您已经到达列表的末尾,您可以在此处添加新节点。如果不是,则递归调用该函数,提供当前的下一个节点。

【讨论】:

    【解决方案3】:

    试试这个:

    typedef struct Nodetype {
       int key;
       struct Node * next;
    } Node;
    
    Node * newNode(int data){
        Node *temp = (Node*)malloc(sizeof(Node));
        temp->key = data;
        temp->next = NULL;
        return temp;
    }
    Node* add(Node * head, int val){
        if(!head)
           return newNode(val);
        head->next = add(head->next, val);
        return head;
    }
    
    Node * delete(Node *head, int val){
         if(!head)
            return NULL;
         Node * temp;
         if(head->key == val){
             temp = head;
             head = head->next;
             free(temp);
         }
         else{
             head->next = delete(head->next, val);
         }
         return head;
    }
    

    您可以根据需要更改代码。我假设一切都是整数。

    【讨论】:

    • 非常感谢!
    • @Nick 如果对您有帮助,请将其标记为答案,以便对其他人有所帮助。
    猜你喜欢
    • 2021-05-29
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-07
    • 2021-05-14
    • 1970-01-01
    相关资源
    最近更新 更多