双向链表实现电话簿主要涉及的知识点就是双向链表的创建,插入,删除操作,涉及到一小点的文件操作。双向链表的插入和删除操作根据删除头结点尾结点中间结点代码不同,其中头结点和尾结点稍许的麻烦因为插入删除都涉及到头指针和尾指针的重新赋值和连接。删除中间结点较为简单,设置一个临时结点指向要删除结点的前向指针前后连接即可。文件操作主要涉及文件的读取操作相对来说比较简单。最难理解的可能就是双向链表的操作。这一部分我会单掕出来记录下自己的见解。代码虽然有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();
}
}