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

Write a recursive algorithm to remove elements from a linked list. Write a recursive algorithm to add elements into a linked list

本文关键字:元素 链表 递归算法 添加 删除      更新时间:2023-10-16

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

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

#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 bookn";
}
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 namen";
}
else
{
if (temp == head)
{
head = head->next;
delete temp;
}
else
{
curr->next = temp->next;
delete temp;
}
cout << pName << " was deleted from the bookn";
}
}
}
void display(AddressBook* head)
{
if (head == NULL)
{
cout << "My book is emptyn";
}
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 emptyn";
}
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 foundnn";
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 bookn";
}
}
}
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 ===============nn";
cout << "1. To add personn";
cout << "2. To display alln";
cout << "3. To delete personn";
cout << "4. To search personn";
cout << "5. Exitn";
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 ===============nn";
cout << "1. To add personn";
cout << "2. To display alln";
cout << "3. To delete personn";
cout << "4. To search personn";
cout << "5. Exitn";
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 bookn";
return head;
}
if (head->name == pName)
{
cout << head->name << " is foundnn";
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 ===============nn";
cout << "1. To add personn";
cout << "2. To display alln";
cout << "3. To delete personn";
cout << "4. To search personn";
cout << "5. Exitn";
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 ===============nn";
cout << "1. To add personn";
cout << "2. To display alln";
cout << "3. To delete personn";
cout << "4. To search personn";
cout << "5. Exitn";
cout << endl;
}
delMemory(head);
return 0;
}

已经发布的内容忽略了问题的很大一部分:在递归函数中请求用户输入只会导致痛苦。要么在每次迭代中请求用户输入,要么需要传递其他控件信息以告诉函数不请求用户输入。两者都是糟糕的计划。

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

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

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 的下一个,并将 NULL 替换为新AddressBook

这让我们回到addPerson

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

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

将类似的过程应用于delPerson

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

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

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

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

试试这个:

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

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