双向链表实现电话簿主要涉及的知识点就是双向链表的创建,插入,删除操作,涉及到一小点的文件操作。双向链表的插入和删除操作根据删除头结点尾结点中间结点代码不同,其中头结点和尾结点稍许的麻烦因为插入删除都涉及到头指针和尾指针的重新赋值和连接。删除中间结点较为简单,设置一个临时结点指向要删除结点的前向指针前后连接即可。文件操作主要涉及文件的读取操作相对来说比较简单。最难理解的可能就是双向链表的操作。这一部分我会单掕出来记录下自己的见解。代码虽然有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);}elsecout<<"警告:申请存储空间失败,不能创建新结点。\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);elseinsertnodeend(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");}elsecout<<"文件结束!";}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);elsereturn(0);
}
void record::deletenode()
{if(current_ptr=head_ptr)deletenodehead();elseif(current_ptr->next==head_ptr)deletenodeend();elsedeletenodemiddle();
}
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();}elsecout<<"打开文件出错\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();}}

双向链表实现电话簿C++代码实现相关推荐

  1. 四、双向链表的操作分析和代码实现

    双向链表 1.双线链表的定义和引入 引入: 单链表的缺点: (1)单向链表查找的方向只能是一个方向,而双向链表可以双向查找 (2)单向链表不能自我删除,需要靠辅助节点 ,而双向链表,则可以自我删除 综 ...

  2. python简易电话簿系统_Python实现电话簿工具(代码分享)

    最近学了下python,用python实现了一个电话簿工具,主要实现思路是:通过字典来存储电话簿信息,以姓名作为主键,以联系人对象作为值存储,最后保存的时候通过python标准库提供的cPickile ...

  3. 约瑟夫环双向链表c语言实,双向链表与约瑟夫环代码

    双向链表 //注意:该文件操作的链表为带头结点双向链表,头结点数据为-1 #include #include #include #define OK 1 #define ERROR 0 typedef ...

  4. 程序员面试题精选100题(01)-把二元查找树转变成排序的双向链表[数据结构]

    题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二元查找树                                     ...

  5. python 双向链表_python算法与数据结构-双向链表(40)

    一.双向链表的介绍 一种更复杂的链表是"双向链表"或"双面链表".每个节点有两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值:而另一个指向下一个节 ...

  6. 剑指offer(C++)-JZ36:二叉搜索树与双向链表(数据结构-树)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.如下图所示 数据范围:输 ...

  7. 双向链表的删除和插入

    一.初始操作 双向链表定义如下: #include<stdio.h>#include<stdlib.h>typedef struct DLnode{int data;struc ...

  8. 双向链表的插入与删除(c++实现)

    目录 前言 双向链表插入节点 实现代码 双向链表删除节点 实现代码 整个项目的完整代码 运行截图 总结 前言 本篇文章主要接着上文的双向链表的创建与遍历(c++实现) 双向链表插入节点 在双向链表中插 ...

  9. LeetCode刷题---707. 设计链表(双向链表-带头尾双结点)

    文章目录 一.编程题:707. 设计链表(双向链表-带头尾双结点) 1.题目描述 2.示例1: 3.提示: 二.解题思路 1.思路 2.复杂度分析: 3.算法图解(双向链表) 三.代码实现 三.单向链 ...

最新文章

  1. 您的凭依不工作/登录没有成功
  2. [开发技巧3]不显示报表直接打印
  3. 【HDU - 1943】Ball bearings(几何问题)
  4. JavaWeb 之 HttpServletResponse
  5. java 装饰流_java装饰流的使用【转】
  6. Redis主从配置,哨兵,集群的设计原理
  7. 2021-07-19交互设计精髓读后感
  8. smplayer变成电视操作步骤
  9. ubuntu查看磁盘分区使用情况命令df
  10. python基础之排列组合以及正则表达式
  11. 设置Notes暗黑模式
  12. 【7gyy】高手分享辨别电脑病毒技巧
  13. 如何自定义火狐背景_在Firefox中自定义菜单
  14. xshell进入桌面_xshell中启动linux图形界面
  15. python初级教练员考试题目_JS | 教练,我想做习题8
  16. win8能直接升级到win11吗
  17. 自动控制原理->绪论
  18. 1.5 DICOM图像CT值转RGB
  19. 洛谷P1496火烧赤壁
  20. python中的Locust是什么

热门文章

  1. 数据战略和风险管理系统
  2. approach for attending ieee conferences
  3. cineware 和ae什么关系
  4. 【BUG记录】记一次游戏越来越卡的BUG
  5. 如何使用Data Lake Analytics创建分区表
  6. C++学习札记(2011-09-30)
  7. Git无法检测到文件名大小写的更改
  8. STM32(Cortex-M3)开发,RVDS和MDK谁优谁劣?
  9. php接口 接受ios或android端图片; php接收NSData数据
  10. java 大数据处理之内存溢出解决办法(一)