#include "stdio.h" /* 链表的归并排序的核心是将链表分成前后两段,分别排序后对两个有序链表归并,递归边界是当前链表长度为1。 */ int compare_count = 0; // 两个有序链表合并 , 将右链元素插入到左链中 。 int *merge(int *l_head, int *r_head) { // 这里构建一个虚拟头结点 , 方便在第一个元素前插入 。 int *head = new int[2]; head[1] = (int)l_head; int *p_left = head; int *p_right = r_head; do { do { // 寻找左链中的插入位置 if (p_left[1] == (int)NULL) break; // count the number of comparisons compare_count++; if (((int *)p_left[1])[0] > p_right[0]) break; p_left = (int *)p_left[1]; } while (1); // 如果到达左链尾端 , 右链直接接上 if (p_left[1] == (int)NULL) { p_left[1] = (int)p_right; break; } int *p_right_temp = p_right; do { // 寻找右链待插入片段 if (p_right_temp[1] == (int)NULL) break; // count the number of comparisons compare_count++; if (((int *)p_right_temp[1])[0] > ((int *)p_left[1])[0]) break; p_right_temp = (int *)p_right_temp[1]; } while (1); // 完成插入操作 int *temp_right_pointer_next = (int *)p_right_temp[1]; p_right_temp[1] = p_left[1]; p_left[1] = (int)p_right; p_left = p_right_temp; p_right = temp_right_pointer_next; if (p_right == NULL) break; } while (1); int rv = head[1]; delete head; return (int *)rv; } // 归并排序主函数 , 先找链表中点 , 再分别排序 , 最后归并 int *msort(int *head) { if (head[1] == (int)NULL) return head; int *stride_2_pointer = head; int *stride_1_pointer = head; do { // 通过同时进行步长为 1 和步长为 2 的跳转找中点 if (stride_2_pointer[1] == (int)NULL) break; stride_2_pointer = (int *)stride_2_pointer[1]; if (stride_2_pointer[1] == (int)NULL) break; stride_2_pointer = (int *)stride_2_pointer[1]; stride_1_pointer = (int *)stride_1_pointer[1]; } while (1); // 拆成两个链表分别排序 , 再归并 。 stride_2_pointer = (int *)stride_1_pointer[1]; stride_1_pointer[1] = (int)NULL; int *l_head = msort(head); int *r_head = msort(stride_2_pointer); return merge(l_head, r_head); } int main() { FILE *infile, *outfile; int buffer[1001]; infile = fopen("a.in", "rb"); fread(buffer, 4, 1001, infile); fclose(infile); int N = buffer[0]; // create a linked list int *head = new int[2]; head[1] = (int)NULL; int *pointer = head; for (int idx = 1; idx <= N; idx++) { pointer[1] = (int)new int[2]; pointer = (int *)pointer[1]; pointer[0] = buffer[idx]; pointer[1] = (int)NULL; } // sort head[1] = (int)msort((int *)head[1]); pointer = head; outfile = fopen("a.out", "wb"); // 输出比较次数 fwrite(&compare_count, 4, 1, outfile); // wirte the sorted list to file do { pointer = (int *)pointer[1]; if (pointer == NULL) break; fwrite(pointer, 4, 1, outfile); } while (1); fclose(outfile); // 本文件用于翻译,没有释放链表内存的操作 return 0; }