fork download
  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stdlib.h>
  4.  
  5. struct worker{
  6. char no[4];
  7. char name[8];
  8. char salary[5];
  9. struct worker *nxt,*pre;
  10. };
  11.  
  12. void merge_lists(struct worker *L1, struct worker *E1, struct worker *L2, struct worker *E2) {
  13. if (L1 == NULL || E1 == NULL || L2 == NULL || E2 == NULL) {
  14. // 如果任一链表为空,则不执行合并
  15. return;
  16. }
  17.  
  18. // 找到L1的最后一个有效节点
  19. struct worker *last_of_L1 = E1->pre;
  20.  
  21. // 找到L2的第一个有效节点
  22. struct worker *first_of_L2 = L2->nxt;
  23.  
  24. // 将L1的最后一个有效节点与L2的第一个有效节点连接起来
  25. last_of_L1->nxt = first_of_L2;
  26. first_of_L2->pre = last_of_L1;
  27.  
  28. // 找到L2的最后一个有效节点
  29. struct worker *last_of_L2 = E2->pre;
  30.  
  31. // 将L2的最后一个有效节点与E1连接起来
  32. last_of_L2->nxt = E1;
  33. E1->pre = last_of_L2;
  34.  
  35. // 释放L2的哑元头尾节点,因为L2已经合并到L1中
  36. free(L2);
  37. free(E2);
  38. }
  39.  
  40. void swap(struct worker *x, struct worker *y) {
  41. char temp_no[4], temp_name[8], temp_salary[5];
  42.  
  43. // 交换编号
  44. strcpy(temp_no, x->no);
  45. strcpy(x->no, y->no);
  46. strcpy(y->no, temp_no);
  47.  
  48. // 交换姓名
  49. strcpy(temp_name, x->name);
  50. strcpy(x->name, y->name);
  51. strcpy(y->name, temp_name);
  52.  
  53. // 交换薪水
  54. strcpy(temp_salary, x->salary);
  55. strcpy(x->salary, y->salary);
  56. strcpy(y->salary, temp_salary);
  57. }
  58.  
  59. void bubbleSort1(struct worker** head) {
  60. int swapped; // 用来标记在一次遍历中是否发生了交换
  61. struct worker *ptr1; // 用于遍历链表的指针
  62. struct worker *lptr = NULL; // 指向已排序部分的最后一个节点
  63.  
  64. if (*head == NULL) return; // 如果链表为空,则直接返回
  65.  
  66. do {
  67. swapped = 0; // 初始化交换标志为0,表示还未发生交换
  68. ptr1 = *head; // 从链表头部开始遍历
  69.  
  70. while (ptr1->nxt != lptr) { // 当没有到达已排序部分的最后一个节点时继续循环
  71. if (strcmp(ptr1->no,ptr1->nxt->no)>0) { // 如果当前节点的编号大于下一个节点的编号,则需要交换
  72. swap(ptr1, ptr1->nxt); // 调用swapWorkers函数交换两个节点
  73. swapped = 1; // 设置交换标志为1,表示发生了交换
  74. }
  75. ptr1 = ptr1->nxt; // 移动到下一个节点
  76. }
  77. lptr = ptr1; // 更新已排序部分的最后一个节点为当前节点
  78. } while (swapped); // 如果在一次遍历中没有发生交换,则表示链表已经排序完成
  79. }
  80.  
  81. void bubbleSort2(struct worker** head2) {
  82. int swapped2; // 用来标记在一次遍历中是否发生了交换
  83. struct worker *ptr2; //用于遍历链表的指针
  84. struct worker *lptr2 = NULL; // 指向已排序部分的最后一个节点
  85.  
  86. if (*head2 == NULL) return; // 如果链表为空,则直接返回
  87.  
  88. do {
  89. swapped2 = 0; // 初始化交换标志为0,表示还未发生交换
  90. ptr2 = *head2; // 从链表头部开始遍历
  91.  
  92. while (ptr2->nxt != lptr2) { // 当没有到达已排序部分的最后一个节点时继续循环
  93. long pr2 = strtol(ptr2->salary,NULL,10);
  94. long pt2 = strtol(ptr2->nxt->salary,NULL,10);
  95. if (pr2 > pt2) { // 如果当前节点的编号大于下一个节点的编号,则需要交换
  96. swap(ptr2, ptr2->nxt); // 调用swapWorkers函数交换两个节点
  97. swapped2 = 1; // 设置交换标志为1,表示发生了交换
  98. }
  99. ptr2 = ptr2->nxt; // 移动到下一个节点
  100. }
  101. lptr2 = ptr2; // 更新已排序部分的最后一个节点为当前节点
  102. } while (swapped2); // 如果在一次遍历中没有发生交换,则表示链表已经排序完成
  103. }
  104.  
  105. int main()
  106. {
  107. int num1;
  108. scanf("%d",&num1);
  109. struct worker *L1, *E1, *p;
  110. L1 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元头节点
  111. E1 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元尾节点
  112. L1->nxt = E1;
  113. L1->pre = NULL;
  114. E1->nxt = NULL;
  115. E1->pre = L1;
  116.  
  117. for(int i = 0; i < num1; ++i){
  118. p = (struct worker*)malloc(sizeof(struct worker));
  119. if(p == NULL){
  120. printf("内存分配失败\n");
  121. return -1; // 如果内存分配失败,则退出程序
  122. }
  123. scanf("%3s %7s %4s", p->no, p->name, p->salary); // 限制输入长度以避免缓冲区溢出
  124. p->nxt = E1;
  125. p->pre = E1->pre;
  126. E1->pre->nxt = p;
  127. E1->pre = p;
  128. }
  129.  
  130. int num2;
  131. scanf("%d",&num2);
  132. struct worker *L2, *E2, *pp;
  133. L2 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元头节点
  134. E2 = (struct worker*)malloc(sizeof(struct worker)); // 创建哑元尾节点
  135. L2->nxt = E2;
  136. L2->pre = NULL;
  137. E2->nxt = NULL;
  138. E2->pre = L2;
  139.  
  140. for(int i = 0; i < num2; ++i){
  141. pp = (struct worker*)malloc(sizeof(struct worker));
  142. if(pp == NULL){
  143. printf("内存分配失败\n");
  144. return -1; // 如果内存分配失败,则退出程序
  145. }
  146. scanf("%3s %7s %4s", pp->no, pp->name, pp->salary); // 限制输入长度以避免缓冲区溢出
  147. pp->nxt = E2;
  148. pp->pre = E2->pre;
  149. E2->pre->nxt = pp;
  150. E2->pre = pp;
  151. }
  152.  
  153. merge_lists(L1, E1, L2, E2);
  154. bubbleSort1(&L1->nxt);
  155.  
  156.  
  157. // 打印合并后的链表
  158. struct worker *ppp = L1->nxt; // 从第一个有效节点开始打印
  159. ppp = ppp->nxt; //add reng
  160. //while (ppp != E1) {
  161. while (ppp != NULL) { // update reng
  162. printf("{%s,%s,%s}\n", ppp->no, ppp->name, ppp->salary);
  163. if (ppp == NULL){break;}
  164. ppp = ppp->nxt;
  165. }
  166.  
  167. bubbleSort2(&L1->nxt);
  168. // 打印合并后的链表
  169. ppp = L1->nxt; // 从第一个有效节点开始打印
  170. ppp = ppp->nxt; // add reng
  171. printf("\n"); // add reng
  172. //while (ppp != E1) { // 确保我们不会打印尾节点
  173. while (ppp != NULL) { // update reng
  174. printf("{%s,%s,%s}\n", ppp->no, ppp->name, ppp->salary);
  175. if (ppp == NULL){break;}
  176. ppp = ppp->nxt; // 移动到下一个节点
  177. }
  178.  
  179. return 0;
  180. }
  181.  
Success #stdin #stdout 0.01s 5280KB
stdin
3
002 name002 3000
005 name005 2500
003 name003 3500
4
006 name006 2800
004 name004 3700
001 name001 3100
007 name007 3600
stdout
{001,name001,3100}
{002,name002,3000}
{003,name003,3500}
{004,name004,3700}
{005,name005,2500}
{006,name006,2800}
{007,name007,3600}

{005,name005,2500}
{006,name006,2800}
{002,name002,3000}
{001,name001,3100}
{003,name003,3500}
{007,name007,3600}
{004,name004,3700}