编写递归算法以从链表中删除元素。编写递归算法以将元素添加到链接列表中

时间:2017-06-09 18:37:46

标签: c++ algorithm recursion linked-list

我在编写添加和删除功能方面遇到了一些困难。 这里有一些用于显示列表,搜索和删除列表的代码。

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

#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;
}

3 个答案:

答案 0 :(得分:0)

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

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);
}

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

答案 1 :(得分:0)

试试这个:

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;
}

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

答案 2 :(得分:0)

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

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

因此我们需要一个函数来从用户那里获取AddressBook:

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。说实话,这应该是一个AddressBook构造函数,但我们可以保存它以用于将来的问题。另请注意,0废话上没有出口。此函数生成AddressBook。期。如果您不想使用AddressBook,则不要调用此函数。让菜单句柄退出。

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

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

同样,一个简单的,愚蠢的函数除了找到列表中的最后一个之外什么都不做。请注意,您将获得对AddressBook指针的引用。这允许您愉快地返回指向NULL的下一个并使用新的AddressBook

替换NULL

这将我们带回addPerson

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

    return head;
}

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

将相似的流程应用于delPerson

注意:我没有运行任何此类操作。可能是一两个错字。