课余 实验 5-3
自行向数据文件中添加 6 条记录,共12条记录,文件内的数据存储形式不变。实现以下功能:
创建两个同类型链表:从文件中读取前5条、后7条记录存入两个链表中。
用 qsort 和 sort 函数对两个链表按电话号码排升序。
将排序后的两个链表合并为一个链表,合并后的链表也是有序的(升序)。
#include <iostream>
#include<fstream>
#include<string>
#include<algorithm>
using namespace std;
typedef struct//一条记录的数据类型
{
string namePY;//姓名拼音
string nameHZ;//汉语名字
unsigned long long int tel;//电话号码
string position;//职位
string addr;//地址
}Record, * pRecord;
typedef struct node//一个结点的数据类型
{
Record data;//一个结点的数据即一条记录
node* next;//指向下一个结点的指针
}Node, * pNode;
pNode initList()//创建一个空链表
{//空表:仅有一个头节点
Node* head = new Node;
if (head == NULL)
{
cout << "内存不足,退出";
exit(0);
}
head->next = NULL;//仅有一个头结点
return head;//一个链表必须知道头结点的指针
}
pNode makeList(int n, ifstream& in)
{//尾插法生成链表
pNode head = initList();//生成空表
pNode tail = head;//尾插法
pNode node;//一个节点,数据域+指针域
Record data;//一个结点的数据(一条记录)
for (int i = 0; i < n; i++)//记录(结点)循环
{//-------读取一条记录------
in >> data.namePY;//读取拼音姓氏
string firstname;
in >> firstname;//读取拼音名字
data.namePY += firstname;
in >> data.nameHZ;
in >> data.tel;
in >> data.position;
in >> data.addr;
//------尾插法生成链表------
node = new Node;
node->data = data;//结点赋值
tail->next = node;//连入链表
tail = node;//尾结点移位
}
tail->next = NULL;
return head;
}
void ShowOneNode(pNode node)//显示节点数据
{
cout << node->data.namePY << " ";
cout << node->data.nameHZ << " ";
cout << node->data.tel << " ";
cout << node->data.position << " ";
cout << node->data.addr << "\n";
}
int TravelList(pNode head, void (*DO)(pNode node))//遍历链表
{
int count = 0;//节点个数(不含头节点)
if (head == NULL)
{
return 0;
}
pNode p = head->next;
while (p != NULL)
{
count++;
(*DO)(p);
p = p->next;
}
return count;
}
void List_DelAll(pNode& head)
{
pNode p;
while (head)
{
p = head;
head = head->next;
delete p;
}
}
bool cmp(Record& elem1, Record& elem2)
{
return(elem1.tel < elem2.tel);
}
int mycmp(const void* a, const void* b)
{
unsigned long long int tel1 = (*(Record*)a).tel;
unsigned long long int tel2 = (*(Record*)b).tel;
return tel1 - tel2;
}
int main()
{
int RecNum;
ifstream infile("电话号码簿.txt");
char* temp = new char[1024];
infile >> temp;
infile >> RecNum;
infile.getline(temp, 1024, '\n');
infile.getline(temp, 1024, '\n');
delete[] temp;
pNode head_a = makeList(5, infile);
pNode head_b = makeList(7, infile);
infile.close();
cout << "-------链表 1----------" << endl;
int na = TravelList(head_a, ShowOneNode);
cout << "-------链表 2----------" << endl;
int nb = TravelList(head_b, ShowOneNode);
cout << "----用 sort 对链表 1 进行排序------" << endl;
Record list1[5];
pNode p1 = head_a->next;
for (int i = 0; i < 5; i++)
{
list1[i].namePY = p1->data.namePY;
list1[i].nameHZ = p1->data.nameHZ;
list1[i].tel = p1->data.tel;
list1[i].position = p1->data.position;
list1[i].addr = p1->data.addr;
p1 = p1->next;
}
sort(list1, list1 + 5, cmp);
p1 = head_a->next;
for (int i = 0; i < 5; i++)
{
p1->data = list1[i];
p1 = p1->next;
}
na = TravelList(head_a, ShowOneNode);
cout << "----用 qsort 对链表 2 进行排序-------" << endl;
Record list2[7];
pNode p2 = head_b->next;
for (int i = 0; i < 7; i++)
{
list2[i].namePY = p2->data.namePY;
list2[i].nameHZ = p2->data.nameHZ;
list2[i].tel = p2->data.tel;
list2[i].position = p2->data.position;
list2[i].addr = p2->data.addr;
p2 = p2->next;
}
qsort(list2, 7, sizeof(Record), mycmp);
p2 = head_b->next;
for (int i = 0; i < 7; i++)
{
p2->data = list2[i];
p2 = p2->next;
}
nb = TravelList(head_b, ShowOneNode);
cout << "----将两个链表合并为一个链表并排序-------" << endl;
Record list[12];
for (int i = 0; i < 5; i++)
{
list[i] = list1[i];
}
for (int i = 0; i < 7; i++)
{
list[i + 5] = list2[i];
}
sort(list, list + 12, cmp);
List_DelAll(head_a);
List_DelAll(head_b);
pNode head = initList();
pNode tail = head;
pNode node;
for (int i = 0; i < 12; i++)
{
node = new Node;
node->data = list[i];
tail->next = node;
tail = node;
}
tail->next = NULL;
int n = TravelList(head, ShowOneNode);
List_DelAll(head);
return 0;
}
vs2019运行截图