C/C++单元实训案例教程——实训13 单链表及操作

课余 实验 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运行截图
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值