📄 shuangxianglianbiao.cpp
字号:
else // 若链表上只有一个接点,将current_ptr
{ // 设为首结点.
current_ptr = head_ptr;
}
return(current_ptr);
} // position_insertion_point的结束
/*********************************************************************/
//实现将新结点设为首结点的功能模块
void List::make_node_new_head(friend_node *new_rec_ptr)
{
friend_node *temp_ptr; // 定义新指针用来保存首接点
temp_ptr = head_ptr; // 使新结点指向首结点
temp_ptr->prev=new_rec_ptr;
new_rec_ptr->next = temp_ptr; // 使新结点的后向指针指向temp_ptr
new_rec_ptr->prev=NULL; // 使新结点的前向指针为空
head_ptr = new_rec_ptr; // 将新接点设为首结点.
} // make_node_new_head的结束
/*********************************************************************/
// 将新结点设为链表的尾结点的功能模块
void List::add_node_to_end(friend_node *new_rec_ptr)
{
new_rec_ptr->next = NULL; // 使新结点的后向指针为空.
move_current_to_end(); // 使current_ptr指向尾结点.
current_ptr->next = new_rec_ptr; // 将新结点设为尾结点.
new_rec_ptr->prev=current_ptr; //使新结点的前向指针指向current_ptr.
} // add_node_to_end的结束
// 使current_ptr指向链表尾结点的功能模块.
void List::move_current_to_end()
{
current_ptr = head_ptr; // 将current_ptr设为首结点.
while(current_ptr->next != NULL)
{ // 沿链表向下查找直至到达尾结点.
current_ptr = current_ptr->next;
}
} // move_current_to_end的结束
/*********************************************************************/
// 实现通过姓名来查找联系人的功能模块,并显示符合条件联系人信息
void List::search_by_fullname()
{
char search_full_string[20]; // 存放被查找人的姓名
current_ptr = head_ptr; // 使current_ptr指向表头开始查找
cin.ignore(20,'\n');
cout << "\n请输入要查找的联系人的姓名: ";
cin.get(search_full_string,20);
cin.ignore(20,'\n');
// 循环直至发现匹配记录或到达链表尾.
while((current_ptr != NULL) &&
((strcmp(current_ptr->full_name, search_full_string) != 0)))
{
current_ptr = current_ptr->next;
}
if(current_ptr != NULL) // 若current_ptr不为空,说明发现联系人.
{
cout << "\n找到该联系人!\n";
cout <<"姓名:"<< current_ptr->full_name <<endl;
cout<<"年龄:"<< current_ptr->age_num << endl;
cout <<"电话号码:"<<current_ptr->phone_num << endl;
getch();
}
else //否则说明未发现.
{
cout << "没有该联系人!\n";
}
} // search_by_fullname的结束.
/*********************************************************************/
// 删除联系人的函数.
void List::delete_record()
{
char search_full_string[20];
friend_node *previous_ptr;
previous_ptr = NULL; // 使previous_ptr为空.
current_ptr = head_ptr; // 使current_ptr指向链表头
cin.ignore(20,'\n');
cout << "\n 请输入要删除人的姓名: ";
cin.get(search_full_string,20); // 来开始查找.
cin.ignore(20,'\n');
// 循环直至发现符合条件的联系人.
while((current_ptr != NULL) &&
((strcmp(current_ptr->full_name, search_full_string) != 0)))
{
previous_ptr = current_ptr; // 必须有一个指针指向要删除的指针
current_ptr = current_ptr->next; // 之前的结点.
}
if(current_ptr != NULL) //如果结点不为空则发现联系人
{
cout << "\n你想要删除的信息如下:\n";
cout <<"姓名:"<< current_ptr->full_name <<endl;
cout << "年龄:"<<current_ptr->age_num << endl;
cout << "电话号码:"<<current_ptr->phone_num << endl;
if(verify_delete()) // 询问用户是否确定删除.
{ // 若确定删除,
delete_node(previous_ptr); // 则删除这个结点.
cout << "\n信息已删除!\n";
}
else // 否则不删除.
{
cout << "\n信息未删除!\n";
}
}
else // 若没有发现符合条件的结点.
{
cout << "\n没有发现你想要的信息!无法删除!\n";
}
} // delete_record的结束
/*********************************************************************/
// 实现询问用户是否确定的函数.
int List::verify_delete()
{
char YesNo;
cout << "\n你确定你的选择吗? (Y/N) ";
cin >> YesNo;
if((YesNo == 'Y') || (YesNo == 'y'))
{
return(1); // 返回“真”.
}
else
{
return(0); // 返回“假”.
}
} // erify_delete的结束
/*********************************************************************/
// 实现删除结点信息的函数.
void List::delete_node(friend_node *previous_ptr)
{
if(current_ptr == head_ptr) // 若要删除的结点是首结点,
{ // 调用一个特殊函数删除首结点.
delete_head_of_list();
}
else
{ // 否则:
if(current_ptr->next == NULL) // 若要删除的结点是尾结点,
{ // 调用一个特殊函数删除尾结点.
delete_end_of_list(previous_ptr);
}
else // 否则:
{
delete_from_middle_of_list(previous_ptr); // 从链表中删除结点.
}
}
} // delete_node的结束
/*********************************************************************/
//删除链表首结点的函数.
void List::delete_head_of_list()
{
current_ptr = head_ptr; // 使current_ptr指向表头.
if(head_ptr->next != NULL)
{ // 若有两个以上结点存在,
head_ptr = current_ptr->next; // 使第二个结点成为链表头.
head_ptr->prev = NULL;
}
else // 否则,使头指针为空
{
head_ptr = NULL;
}
delete current_ptr; // 删除结点.
} // delete_head_of_list的结束
/*********************************************************************/
// 删除链表尾结点的函数.
void List::delete_end_of_list(friend_node *previous_ptr)
{
delete current_ptr; // 删除结点.
previous_ptr->next = NULL; // 使删除结点的上一个结点指向链表尾.
current_ptr = head_ptr; // 将current_ptr设为表头.
} // delete_end_of_list的结束
/*********************************************************************/
// 从链表中删除一个结点的函数.
void List::delete_from_middle_of_list(friend_node *previous_ptr)
{
// 连接删除结点的前后结点
previous_ptr->next = current_ptr->next;
current_ptr->next->prev=previous_ptr;
delete current_ptr; // 删除结点.
current_ptr = head_ptr; // 将current_ptr设为表头.
} // delete_from_middle_of_list的结束
/*********************************************************************/
// 释放链表所占用的空间.
void List::delete_list()
{
friend_node *temp_ptr; // 保存指针
current_ptr = head_ptr; // 使current_ptr指向链表头.
do // 沿链表删除各结点.
{
temp_ptr = current_ptr->next; // 使temp_ptr指向链表中剩下的结点
delete current_ptr; // 删除结点.
current_ptr = temp_ptr; // 使current_ptr指向尚未删除的结点
} while(temp_ptr != NULL);
} // delete_list的结束
/*********************************************************************/
// 将记录保存在文件里的函数.
void List::write_list_to_file()
{
ofstream outfile; // 声明文件输出流类
outfile.open("通讯录.DAT",ios::out); // 以写入方式打开文件.
if (outfile) // 若打开文件正常进行,
{ // 将记录写入文件.
current_ptr = head_ptr; // 使current_ptr指向表头.
if(head_ptr != NULL) // 若链表不为空,
{ // 开始写入记录.
do // 沿链表向下直至到达链表尾.
{
// 将结点信息写入文件.
outfile << current_ptr->full_name << endl;
outfile << current_ptr->age_num << endl;
outfile << current_ptr->phone_num << endl;
current_ptr = current_ptr->next; // 使当前指针后移.
} while(current_ptr != NULL); // 循环直至到达链表尾.
}
// “文件尾”使从文件中读取记录时容易确定读取结束位置
outfile << "END OF FILE" << endl;
outfile.close(); // 关闭文件.
}
else // 若打开文件错误,显示提示信息.
{
cout << "打开文件错误!.\n";
}
} // write_list_to_file的结束
/*********************************************************************/
// 从文件中读取信息的函数.
void List::load_list_from_file() // 从数据文件FRIENDS.DAT中
{ //读取数据重建链表处理函数
friend_node *new_rec_ptr;
ifstream infile; // 声明文件输入流类
int end_loop = 0;
infile.open("通讯录.DAT",ios::in); // 打开文件.
if (infile) // 若打开文件正常
{
do
{
new_rec_ptr = new friend_node; // 动态分配内存空间.
if(new_rec_ptr != NULL) // 检查是否分配成功.
{
// 从文件中读取下一个姓.
infile.get(new_rec_ptr->full_name,20);
infile.ignore(20,'\n');
// 若未到达文件尾,继续读取.
if((strcmp(new_rec_ptr->full_name, "") != 0) &&
(strcmp(new_rec_ptr->full_name, "END OF FILE") != 0))
{
infile.get(new_rec_ptr->age_num, 15);
infile.ignore(20,'\n');
infile.get(new_rec_ptr->phone_num, 15);
infile.ignore(20,'\n');
insert_node(new_rec_ptr);
}
else // 若到达文件尾,释放用NEW动态分配的内存空间
{ // 并将end_loop设为1.
delete new_rec_ptr;
end_loop = 1;
}
}
else // 若读取失败,显示信息并将end_loop设为1.
{
cout << "警告:记忆系统出错!无法读取文件!\n";
end_loop = 1;
}
} while(end_loop == 0); // 循环直至end_loop为1.
infile.close(); // 关闭文件.
}
else // 若打开文件失败,显示提示信息.
{
cout << "找不到可打开的文件. 链表为空.\n";
}
} // load_list_from_file的结束
/*********************************************************************/
//修改记录的函数
void List::modify_record(){
cout<<"\n查找要修改的联系人:\n";
search_by_fullname(); //通过全名查找要修改的结点
if(current_ptr!=NULL){
char age[15],num[12]; //存放年龄及电话号码
cout<<"请按回车键修改联系人信息\n"; //读取新的结点信息
cin.ignore(20,'\n');
cout<<"请输入年龄:\n";
cin.get(age,15);cin.ignore(20,'\n');
cout<<"电话号码:\n";
cin.get(num,12);
cout<<"你确实要把"<<'\n';
cout<<current_ptr->age_num<<"(年龄)"<<","<<current_ptr->phone_num<<"(电话号码)"<<'\t';
cout<<"替换为:";
cout<<age<<"(年龄)"<<','<<num<<"(电话号码)"<<"吗?"<<'\n';
if(verify_delete()){ // 若用户选择确定,
// 则修改结点信息.
strcpy(current_ptr->age_num,age);
strcpy(current_ptr->phone_num,num);
cout<<"修改成功!\n";
}
else cout<<"你放弃了修改!\n";} // 否则放弃修改
cin.ignore(20,'\n');
}//修改功能的结束
/*********************************************************************/
//计算链表中结点个数的函数
void List::lenghtoflist()
{
ptr_num=0; //将结点数设为0
friend_node *p=head_ptr; //定义指针使之指向表头
if(p!=NULL){ //若链表不为空
do{
ptr_num++; //增加ptr_num
p=p->next;
}while(p!=NULL); //循环直至到达链表尾
}
}//计算结点数功能的结束
/*********************************************************************/
void swap(char *a1,char *a2){
char *pp;
pp=a1;a1=a2;a2=pp;}
void List::paixuoflist(){
friend_node *p1,*p2;
char *Fullname1,*Fullname2,*Agenum1,*Agenum2,*Phonenum1,*Phonenum2;
lenghtoflist();
for(int i=0;i<ptr_num-1;i++){
p1=head_ptr;p2=head_ptr->next;
for(int l=i;l<ptr_num-1;l++){
if(strcmp(p1->full_name,p2->full_name)>0){
Fullname2=p1->full_name;
Fullname1=p2->full_name;
swap(Fullname1,Fullname2);
Agenum2=p1->age_num;
Agenum1=p2->age_num;
swap(Agenum1,Agenum2);
Phonenum1=p1->phone_num;
Phonenum2=p2->phone_num;
swap(Phonenum1,Phonenum2);
}
p1=p2;p2=p2->next;
}
}
}
/*********************************************************************/
// 显示整个链表上结点信息的功能模块.
void List::display_list()
{
if(head_ptr!=NULL){
char fullname[36]; //用来存放全名,包括姓及名
friend_node *dis_ptr;//定义类friend_node的指针
dis_ptr = head_ptr; // 并使它指向链表首.
cout << endl;
cout << "姓名 年龄 电话号码\n";
cout << "----------------------------------- ------------\n";
do{
strcpy(fullname,""); // 清除fullname.
strcat(fullname, dis_ptr->full_name); // 将姓、空格及名
strcat(fullname, " "); // 放入fullname中
strcat(fullname, dis_ptr->age_num);
cout.setf(ios::left);
cout << setw(36) << fullname;
cout.unsetf(ios::left);
cout.setf(ios::right);
cout << setw(12) << dis_ptr->phone_num << endl;
dis_ptr = dis_ptr->next; // 使dis_ptr指向下一个结点.
cout << endl;
}while(dis_ptr!=NULL); // 循环直至选择退出,
cout << "----------------------------------- ------------\n";
cin.ignore(1,pause); // 或到达链表尾.
cout << "按回车继续...... \n";
cin.ignore(1,pause);
system("cls");
}
else cout<<"你暂时没有联系人!\n\n\n\n";
} // display_list的结束
/*********************************************************************/
friend_node::friend_node() //定义构造函数
{
prev=0;next=0;
strcpy(full_name,"");
strcpy(age_num,"");
strcpy(phone_num,"");
}
friend_node::~friend_node() //定义析构函数
{prev=0;next=0;}
List::List() //定义构造函数
{
head_ptr=NULL;
current_ptr=NULL;
}
List::~List(){}
/*********************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -