#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct worker{
char no[4];
char name[8];
char salary[5];
struct worker *nxt,*pre;
};
void merge_lists(struct worker *L1, struct worker *E1, struct worker *L2, struct worker *E2) {
if (L1 == NULL || E1 == NULL || L2 == NULL || E2 == NULL) {
// 如果任一链表为空,则不执行合并
return;
}
// 找到L1的最后一个有效节点
struct worker *last_of_L1 = E1->pre;
// 找到L2的第一个有效节点
struct worker *first_of_L2 = L2->nxt;
// 将L1的最后一个有效节点与L2的第一个有效节点连接起来
last_of_L1->nxt = first_of_L2;
first_of_L2->pre = last_of_L1;
// 找到L2的最后一个有效节点
struct worker *last_of_L2 = E2->pre;
// 将L2的最后一个有效节点与E1连接起来
last_of_L2->nxt = E1;
E1->pre = last_of_L2;
// 释放L2的哑元头尾节点,因为L2已经合并到L1中
free(L2);
free(E2);
}
void swap(struct worker *x, struct worker *y) {
char temp_no[4], temp_name[8], temp_salary[5];
// 交换编号
strcpy(temp_no, x->no);
strcpy(x->no, y->no);
strcpy(y->no, temp_no);
// 交换姓名
strcpy(temp_name, x->name);
strcpy(x->name, y->name);
strcpy(y->name, temp_name);
// 交换薪水
strcpy(temp_salary, x->salary);
strcpy(x->salary, y->salary);
strcpy(y->salary, temp_salary);
}
void bubbleSort1(struct worker** head) {
int swapped; // 用来标记在一次遍历中是否发生了交换
struct worker *ptr1; // 用于遍历链表的指针
struct worker *lptr = NULL; // 指向已排序部分的最后一个节点
if (*head == NULL) return; // 如果链表为空,则直接返回
do {
swapped = 0; // 初始化交换标志为0,表示还未发生交换
ptr1 = *head; // 从链表头部开始遍历
while (ptr1->nxt != lptr) { // 当没有到达已排序部分的最后一个节点时继续循环
if (strcmp(ptr1->no,ptr1->nxt->no)>0) { // 如果当前节点的编号大于下一个节点的编号,则需要交换
swap(ptr1, ptr1->nxt); // 调用swapWorkers函数交换两个节点
swapped = 1; // 设置交换标志为1,表示发生了交换
}
ptr1 = ptr1->nxt; // 移动到下一个节点
}
lptr = ptr1; // 更新已排序部分的最后一个节点为当前节点
} while (swapped); // 如果在一次遍历中没有发生交换,则表示链表已经排序完成
}
void bubbleSort2(struct worker** head2) {
int swapped2; // 用来标记在一次遍历中是否发生了交换
struct worker *ptr2; //用于遍历链表的指针
struct worker *lptr2 = NULL; // 指向已排序部分的最后一个节点
if (*head2 == NULL) return; // 如果链表为空,则直接返回
do {
swapped2 = 0; // 初始化交换标志为0,表示还未发生交换
ptr2 = *head2; // 从链表头部开始遍历
while (ptr2->nxt != lptr2) { // 当没有到达已排序部分的最后一个节点时继续循环
long pr2 = strtol(ptr2->salary,NULL,10);
long pt2 = strtol(ptr2->nxt->salary,NULL,10);
if (pr2 > pt2) { // 如果当前节点的编号大于下一个节点的编号,则需要交换
swap(ptr2, ptr2->nxt); // 调用swapWorkers函数交换两个节点
swapped2 = 1; // 设置交换标志为1,表示发生了交换
}
ptr2 = ptr2->nxt; // 移动到下一个节点
}
lptr2 = ptr2; // 更新已排序部分的最后一个节点为当前节点
} while (swapped2); // 如果在一次遍历中没有发生交换,则表示链表已经排序完成
}
int main()
{
int num1;
scanf("%d",&num1);
struct worker *L1, *E1, *p;
L1 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元头节点
E1 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元尾节点
L1->nxt = E1;
L1->pre = NULL;
E1->nxt = NULL;
E1->pre = L1;
for(int i = 0; i < num1; ++i){
p = (struct worker*)malloc(sizeof(struct worker));
if(p == NULL){
printf("内存分配失败\n");
return -1; // 如果内存分配失败,则退出程序
}
scanf("%3s %7s %4s", p->no, p->name, p->salary); // 限制输入长度以避免缓冲区溢出
p->nxt = E1;
p->pre = E1->pre;
E1->pre->nxt = p;
E1->pre = p;
}
int num2;
scanf("%d",&num2);
struct worker *L2, *E2, *pp;
L2 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元头节点
E2 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元尾节点
L2->nxt = E2;
L2->pre = NULL;
E2->nxt = NULL;
E2->pre = L2;
for(int i = 0; i < num2; ++i){
pp = (struct worker*)malloc(sizeof(struct worker));
if(pp == NULL){
printf("内存分配失败\n");
return -1; // 如果内存分配失败,则退出程序
}
scanf("%3s %7s %4s", pp->no, pp->name, pp->salary); // 限制输入长度以避免缓冲区溢出
pp->nxt = E2;
pp->pre = E2->pre;
E2->pre->nxt = pp;
E2->pre = pp;
}
merge_lists(L1, E1, L2, E2);
bubbleSort1(&L1->nxt);
// 打印合并后的链表
struct worker *ppp = L1->nxt; // 从第一个有效节点开始打印
ppp = ppp->nxt; //add reng
//while (ppp != E1) {
while (ppp != NULL) { // update reng
printf("{%s,%s,%s}\n", ppp->no, ppp->name, ppp->salary);
if (ppp == NULL){break;}
ppp = ppp->nxt;
}
bubbleSort2(&L1->nxt);
// 打印合并后的链表
ppp = L1->nxt; // 从第一个有效节点开始打印
ppp = ppp->nxt; // add reng
printf("\n"); // add reng
//while (ppp != E1) { // 确保我们不会打印尾节点
while (ppp != NULL) { // update reng
printf("{%s,%s,%s}\n", ppp->no, ppp->name, ppp->salary);
if (ppp == NULL){break;}
ppp = ppp->nxt; // 移动到下一个节点
}
return 0;
}