双向链表实现电话簿C++代码实现

38 篇文章 1 订阅

双向链表实现电话簿主要涉及的知识点就是双向链表的创建,插入,删除操作,涉及到一小点的文件操作。双向链表的插入和删除操作根据删除头结点尾结点中间结点代码不同,其中头结点和尾结点稍许的麻烦因为插入删除都涉及到头指针和尾指针的重新赋值和连接。删除中间结点较为简单,设置一个临时结点指向要删除结点的前向指针前后连接即可。文件操作主要涉及文件的读取操作相对来说比较简单。最难理解的可能就是双向链表的操作。这一部分我会单掕出来记录下自己的见解。代码虽然有500多行,但很多是双向链表插入删除等重复的操作,最主要的还是心中要有整体的框架。知道类内包含哪些函数。代码如下:

参考资料:谭浩强C++程序设计实践

#include<fstream>
#include<iostream>
#include<iomanip>
#include<string>
#include<cstring>
#include<cstdlib>
using namespace std;
namespace NameRecord
{
	struct friend_node
	{
		char last_name[20];
		char first_name[15];
		char phone_num[12];
		friend_node *next;
		friend_node *prior;
	};
		friend_node *head_ptr;
		friend_node *tail_ptr;
		friend_node *current_ptr;
		char pause;
		class record
		{
			public:
					void userchoice(int choice);
					void insertrecord();
					void insertnode(friend_node *new_tr);
					void insertnodehead(friend_node *new_tr);
					void insertnodeend(friend_node *new_tr);
					void showlist();
					void deleterecord();
					void deletenodehead();
					void deletenodeend();
					void deletenodemiddle();
					int verifydelete();
					void deletenode();
					void deletelist();
					void searchbylastname();
					void savefile();
					void loadfile();
					//void help();
					void modifyrecord();
					void userinput();	
		};	
} 
using namespace NameRecord;
int main()
{
	record myrecord;
	cout<<"欢迎使用电话本\n";
	cout<<"按enter键继续\n";
	cin.get(pause);
	system("cls");
	int choice;
	head_ptr=NULL;
	tail_ptr=NULL;
	myrecord.loadfile();
	do
	{
		cout<<"1_新增记录\n";
		cout<<"2_显示所有记录\n";
		cout<<"3_按姓氏搜索记录\n";
		cout<<"4_删除记录\n";
		cout<<"5_修改记录\n";
		cout<<"6_帮助\n";
		cout<<"7_退出程序\n";
		cout<<"输入你的选择:";
		cin>>choice;
		myrecord.userchoice(choice);
	}while(choice!=7);
	return 0;
}
void record::userchoice(int choice)
{
	switch(choice)
	{
		case 1:
			insertrecord();
			break;
		case 2:
			showlist();
			break;
		case 3:
			searchbylastname();
			break;
		case 4:
			deleterecord();
			break;
		case 5:
			modifyrecord();
			break;
	//	case 6:
	//		help();
	//		break;
		case 7:
			savefile();
			if(head_ptr!=NULL)
			deletelist();
			break;
		default:
			cout<<"选择无效\n";
			break; 
	}
}
void record::insertrecord()
{
	friend_node *new_ptr;
	new_ptr=new friend_node;
	if(new_ptr!=NULL)
	{
		system("cls");
		cin.ignore(20,'\n');
		cout<<"名字";
		cin.getline(new_ptr->first_name,15);
		cout<<"姓氏";
		cin.getline(new_ptr->last_name,20);
		cout<<"电话号码";
		cin.getline(new_ptr->phone_num,15);
		insertnode(new_ptr);
	}
	else
	cout<<"警告:申请存储空间失败,不能创建新结点。\n";
	system("cls");
}
void record::insertnode(friend_node *new_ptr)
{
	system("cls");
	friend_node *temp_ptr;
	//情况1:双向链表为空 
	if(head_ptr==NULL)
	{
		new_ptr->next=new_ptr;
		new_ptr->prior=new_ptr;
		head_ptr=new_ptr;
		tail_ptr=new_ptr;
	}
	//双向链表只有一个结点 
	if(head_ptr->next==head_ptr)
	{
		if(strcmp(new_ptr->last_name,head_ptr->last_name)<0)
		insertnodehead(new_ptr);
		else
		insertnodeend(new_ptr);
		return;
	 } 
	 //情况3:如果链表中不是只有一个结点
	 if(head_ptr->next!=head_ptr)
	 {
	 	current_ptr=head_ptr->next;
	 	while((strcmp(new_ptr->last_name,current_ptr->last_name)>0)&&(current_ptr!=head_ptr))
	 	current_ptr=current_ptr->next;
	 	if(current_ptr==head_ptr)
	 		insertnodeend(new_ptr);
	 	else
	 		{
	 			temp_ptr=current_ptr->prior;
				temp_ptr->next=new_ptr;
				new_ptr->prior=temp_ptr;
				current_ptr->prior=new_ptr;
				new_ptr->next=current_ptr;
			 }
		return;
	  } 
}
void record::insertnodehead(friend_node *new_ptr)
{
	new_ptr->next=head_ptr;
	new_ptr->prior=tail_ptr;
	head_ptr->prior=new_ptr;
	tail_ptr->next=new_ptr;
	head_ptr=new_ptr;
}
void record::insertnodeend(friend_node *new_ptr)
{
	new_ptr->next=head_ptr;
	tail_ptr->prior=new_ptr;
	new_ptr->prior=tail_ptr;
	head_ptr->next=new_ptr;
	tail_ptr=new_ptr;
}
void record::showlist() 
{
	system("cls");
	int n;
	cout<<"请输入每屏显示的数目(不得大于20):\n";
	cin>>n;
	system("cls");
	int i;
	char fullname[36];
	current_ptr=head_ptr;
	do
	{
		i=1;
		cout<<setw(20)<<"Name"<<setw(20)<<"Phone Number\n";
		do
		{
			strcpy(fullname,current_ptr->last_name);
			strcat(fullname,",");
			strcat(fullname,current_ptr->first_name);
			cout<<setw(20)<<fullname<<setw(20)<<current_ptr->phone_num<<endl;
			current_ptr=current_ptr->next;
			i++;
		}while(current_ptr!=head_ptr&&i<=n);
		cin.get(pause);
		if(current_ptr!=head_ptr)
		{
			cout<<"请按enter键继续";
			cin.get(pause);
			system("cls");
		}
		else
			cout<<"文件结束!";
	}while(current_ptr!=head_ptr);
	cin.get(pause);
	cin.ignore(1,pause);
	system("cls");
}
void record::searchbylastname()
{
	system("cls");
	int nflag=0;
	char search_string[20];
	current_ptr=head_ptr;
	if(current_ptr==NULL)
	cout<<"电话记录为空";
	else
	{
		cin.ignore(20,'\n');
		cout<<"输入你要搜索记录的姓氏";
		cin.getline(search_string,20);
		if(strcmp(current_ptr->last_name,search_string)==0)
		{
			if(nflag==0)
			cout<<"找到结点\n";
			nflag=1;
			cout<<current_ptr->first_name<<' '<<current_ptr->last_name<<"\t\t";
			cout<<current_ptr->phone_num<<endl; 
		}
		current_ptr=current_ptr->next;
		while(current_ptr!=head_ptr)
		{
			if(strcmp(current_ptr->last_name,search_string)==0)
			{
				if(nflag==0)
				cout<<"找到记录\n";
				nflag=1;
				cout<<current_ptr->first_name<<' '<<current_ptr->last_name<<"\t\t";
				cout<<current_ptr->phone_num<<endl;
			}
			current_ptr=current_ptr->next;
		}
		if(nflag==0)
			{
				cout<<"无记录!";
				cin.get(pause);
				system("cls");
			}
	}
}
void record::deleterecord()
{
	system("cls");
	char search_string[20];
	friend_node *previous_ptr;
	previous_ptr=NULL;
	current_ptr=head_ptr;
	if(current_ptr==NULL)
	{
		cout<<"没有要删除的记录";
		return;
	}
	cin.ignore(20,'\n');
	int nflag=0;
	cout<<"\n输入你要删除结点的姓氏";
	cin.getline(search_string,20);
	while((strcmp(current_ptr->last_name,search_string)==0)&&head_ptr!=NULL)
	{
		nflag=1;
		cout<<"\n找到记录\n";
		cout<<current_ptr->first_name<<' '<<current_ptr->last_name<<"\t\t";
		cout<<current_ptr->phone_num<<endl;
		if(verifydelete())
		{
			deletenode();
			cout<<"\n记录已删除\n";
		}
		else
		{
			cout<<current_ptr->first_name<<","<<current_ptr->last_name<<"\t"<<current_ptr->phone_num<<"  的记录没有删除\n";
			current_ptr=current_ptr->next;
		}
	 }
	 do{
	 	if(strcmp(current_ptr->last_name,search_string)==0)
	 	{
	 		nflag=1;
	 		cout<<"\n找到记录\n";
	 		cout<<current_ptr->first_name<<' '<<current_ptr->last_name<<"\t\t";
	 		cout<<current_ptr->phone_num<<endl;
	 		if(verifydelete())
	 		{
	 			deletenode();
	 			cout<<"\n记录已删除\n";
			 }
			 else
			 {
			 	cout<<current_ptr->first_name<<','<<current_ptr->last_name<<"\t"<<current_ptr->phone_num<<" 的记录没有删除\n";
			 }
		 }
		 current_ptr=current_ptr->next;
	 } while((current_ptr!=head_ptr||head_ptr==NULL));
	 if(nflag==0)
	 cout<<"\n没有找到相符的记录也没有删除记录\n";
	 cin.get();
	 system("cls");
}
int record::verifydelete()
{
	char yesno;
	cout<<"\n确认?(y/n)";
	cin>>yesno;
	cin.ignore(20,'\n');
	if((yesno=='Y')||(yesno=='y'))
	return(1);
	else
	return(0);
}
void record::deletenode()
{
	if(current_ptr=head_ptr)
	deletenodehead();
	else
		if(current_ptr->next==head_ptr)
		deletenodeend();
		else
		deletenodemiddle();
}
void record::deletenodehead()
{
	if(head_ptr->next!=head_ptr)
	{
		head_ptr=current_ptr->next;
		tail_ptr->next=head_ptr;
		head_ptr->prior=tail_ptr;
		delete current_ptr;
		current_ptr=head_ptr;
	}
	else
	{
		head_ptr=NULL;
		tail_ptr=NULL;
		delete current_ptr;
	}
}
void record::deletenodeend()
{
	friend_node *previous_ptr=current_ptr->prior;
	delete current_ptr;
	previous_ptr->next=head_ptr;
	head_ptr->prior=previous_ptr;
	tail_ptr=previous_ptr;
	current_ptr=tail_ptr;
}
void record::deletenodemiddle()
{
	friend_node *previous_ptr=current_ptr->prior;
	previous_ptr->next=current_ptr->next;
	current_ptr->next->prior=previous_ptr;
	delete current_ptr;
	current_ptr=previous_ptr;
}
void record::deletelist()
{
	friend_node *temp_ptr;
	current_ptr=head_ptr;
	do
	{
		temp_ptr=current_ptr->next;
		tail_ptr->prior=temp_ptr;
		temp_ptr->prior=tail_ptr;
		delete current_ptr;
		current_ptr=temp_ptr;
	}while(temp_ptr!=NULL&&temp_ptr!=tail_ptr);
	delete current_ptr;
}
void record::savefile()
{
	ofstream outfile;
	outfile.open("FRIENDS.dat",ios::out);
	if(outfile)
	{
		current_ptr=head_ptr;
		if(head_ptr!=NULL)
		{
			do{
				outfile<<current_ptr->last_name<<endl;
				outfile<<current_ptr->first_name<<endl;
				outfile<<current_ptr->phone_num<<endl;
				current_ptr=current_ptr->next;
			}while(current_ptr!=head_ptr);
		}
		outfile<<"文件结束"<<endl;
		outfile.close();
	}
	else
	cout<<"打开文件出错\n";
}
void record::loadfile()
{
	friend_node *new_ptr;
	ifstream infile;
	int end_lop=0;
	if(infile)
	{
		do{
			new_ptr=new friend_node;
			if(new_ptr!=NULL)
			{
				infile.get(new_ptr->last_name,20);
				infile.ignore(20,'\n');
				if((strcmp(new_ptr->last_name,"")!=0)&&(strcmp(new_ptr->last_name,"文件结束")!=0))
				{
					infile.get(new_ptr->first_name,15);
					infile.ignore(20,'\n');
					infile.get(new_ptr->phone_num,15);
					infile.ignore(20,'\n');
					insertnode(new_ptr);
				}
				else
				{
					delete new_ptr;
					end_lop=1;
				}
			}
			else{
				cout<<"警告:没有成功从磁盘导入文件.\n";
				end_lop=1;
			}
		}while(end_lop==0);
		infile.close();
	}
	else 
	cout<<"没有可用的数据文件,记录表为空\n";
}
void record::modifyrecord()
{
	system("cls");
	char search_string[20];
	if(head_ptr==NULL)
	{
		cout<<"无记录可修改\n";
		return;
	}
	int nflag=0;
	current_ptr=head_ptr;
	cin.ignore(20,'\n');
	cout<<"\n输入你想修改记录的姓氏";
	cin.getline(search_string,20);
	friend_node *new_ptr;
	while((strcmp(current_ptr->last_name,search_string)==0)&&head_ptr!=NULL)
	{
		new_ptr=new friend_node;
		nflag=1;
		cout<<"\n找到记录\n";
		cout<<current_ptr->first_name<<' '<<current_ptr->last_name<<"\t\t";
		cout<<current_ptr->phone_num<<endl;
		if(verifydelete())
		{
			cout<<"请输入新记录的姓氏";
			cin.getline(new_ptr->last_name,20);
			cout<<"请输入新记录的名字";
			cin.getline(new_ptr->first_name,15);
			cout<<"请输入新记录的电话";
			cin.getline(new_ptr->phone_num,12);
			if(verifydelete())
			{
				deletenode();
				insertnode(new_ptr);
				cout<<"\n记录已修改\n";
				cout<<new_ptr->first_name<<' ';
				cout<<new_ptr->last_name<<endl;
				cout<<new_ptr->phone_num<<endl;
				current_ptr=head_ptr;
			}
		 }
		 else
		 {
		 	cout<<current_ptr->first_name<<","<<current_ptr->last_name<<"\t"<<current_ptr->phone_num<<" 的记录没有被修改\n";
		 	current_ptr=current_ptr->next;
		 	delete new_ptr;
		  } 
	}
	do{
		if(strcmp(current_ptr->last_name,search_string)==0)
		{
			nflag=1;
			new_ptr=new friend_node;
			cout<<"\n找到记录\n";
			cout<<current_ptr->first_name<<' '<<current_ptr->last_name<<"\t\t";
			cout<<current_ptr->phone_num<<endl;
			if(verifydelete())
			{
				cout<<"请输入新记录的姓氏";
				cin.getline(new_ptr->last_name,20);
				cout<<"请输入新记录的名字";
				cin.getline(new_ptr->first_name,15);
				cout<<"请输入新记录的电话";
				cin.getline(new_ptr->phone_num,12);
				if(verifydelete())
				{
					friend_node *temp_ptr=current_ptr->prior;
					deletenode();
					insertnode(new_ptr);
					current_ptr=temp_ptr;
					cout<<"\n记录已修改\n";
					cout<<new_ptr->first_name<<' ';
					cout<<new_ptr->last_name<<endl;
					cout<<new_ptr->phone_num<<endl;
				}
			}
			else
			{
				cout<<current_ptr->first_name<<","<<current_ptr->last_name<<"\t"<<current_ptr->phone_num<<" 的记录没有被修改\n";
				delete new_ptr;
			}
		}
			current_ptr=current_ptr->next;
	}while(current_ptr!=head_ptr||head_ptr==NULL);
	if(nflag==0)
	{
		cout<<"找不到相符合的记录";
		userinput();
	}
	system("cls");
 } 
 void record::userinput()
 {
 	char answer_y_n;
 	cout<<"再试一次?y/n";
 	cin.get(answer_y_n);
 	if(answer_y_n=='y'||answer_y_n=='y')
 		if(answer_y_n=='y')
 		modifyrecord();
 	else
 	{
 		cout<<"无效输入";
 		userinput();
	 }
 }

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用 C++ 实现双向链表的通讯录的示例代码: ```c++ #include <iostream> #include <string> using namespace std; // 定义联系人结构体 struct Contact { string name; string phone; }; // 定义双向链表节点结构体 struct ListNode { Contact data; ListNode* prev; ListNode* next; ListNode(Contact value): data(value), prev(nullptr), next(nullptr) {} }; // 定义双向链表类 class DoubleLinkedList { private: ListNode* head; ListNode* tail; int size; public: DoubleLinkedList(): head(nullptr), tail(nullptr), size(0) {} ~DoubleLinkedList() { ListNode* p = head; while (p != nullptr) { ListNode* q = p->next; delete p; p = q; } head = tail = nullptr; size = 0; } void append(Contact value) { ListNode* node = new ListNode(value); if (tail == nullptr) { head = tail = node; } else { tail->next = node; node->prev = tail; tail = node; } size++; } void remove(ListNode* node) { if (node == nullptr) return; if (node == head) { head = head->next; if (head != nullptr) { head->prev = nullptr; } else { tail = nullptr; } } else if (node == tail) { tail = tail->prev; if (tail != nullptr) { tail->next = nullptr; } else { head = nullptr; } } else { node->prev->next = node->next; node->next->prev = node->prev; } delete node; size--; } void print() { ListNode* p = head; while (p != nullptr) { cout << "Name: " << p->data.name << ", Phone: " << p->data.phone << endl; p = p->next; } } int getSize() { return size; } }; int main() { DoubleLinkedList contacts; Contact c1 = {"Alice", "123456789"}; Contact c2 = {"Bob", "234567890"}; Contact c3 = {"Charlie", "345678901"}; contacts.append(c1); contacts.append(c2); contacts.append(c3); contacts.print(); cout << "Size: " << contacts.getSize() << endl; // 删除 Bob 的联系方式 ListNode* p = contacts.head; while (p != nullptr) { if (p->data.name == "Bob") { contacts.remove(p); break; } p = p->next; } contacts.print(); cout << "Size: " << contacts.getSize() << endl; return 0; } ``` 上述代码实现了一个基本的双向链表类,其中节点结构体 `ListNode` 包括了联系人结构体 `Contact` 和前驱节点和后继节点指针。在主函数中,我们创建了三个联系人并添加到双向链表中,然后打印出链表中所有联系人的信息。接着,我们使用循环遍历链表,找到名字为 Bob 的联系人并删除它,最后再次打印出链表中剩余的联系人信息和链表大小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值