思路:
(1)找到中间节点,将原链表一分为二
(2)后半段链表原地逆置
(3)合并链表
#include <stdio.h> #include <stdlib.h> //定义节点类型 typedef struct LNode { int data;//数据域 struct LNode *next;//指针域 } LNode, *LinkList; void tailList(LinkList &l) { l = (LinkList) malloc(sizeof(LNode)); l->next = NULL; int x; scanf("%d", &x);//s指向新节点,r指向链表尾 LinkList s, r = l; while (x != 9999) { s = (LinkList) malloc(sizeof(LNode));//s存储了这个节点的起始地址.s指向此节点 s->data = x; r->next = s;//新节点给尾节点next指针 r = s;//r指向新的尾部 scanf("%d", &x); } r->next = NULL; } void printList(LinkList L) { L = L->next; while (L != NULL) { printf("%d", L->data);//打印当前结点数据 L = L->next;//指向下一个结点 if (L != NULL) { printf(" "); } } printf("\n"); } void findMiddle(LinkList l, LinkList &l2) { l2 = (LinkList) malloc(sizeof(LNode)); //双指针法遍历,前指针走两次,后指针走一次 LinkList pcur = l->next; LinkList ppre = l->next; while (pcur) { pcur = pcur->next; if (pcur == NULL) { break; } pcur = pcur->next; if (pcur == NULL) { break; } ppre = ppre->next; } l2->next = ppre->next; ppre->next = NULL; } //三指针逆置链表 void reverseList(LinkList l2) { LinkList r, s, t; r = l2->next; if (r == NULL) {//可能无节点 return; } s = r->next; if (s == NULL) { return; } t = s->next; while (t) { //第二个节点指向第一个节点 s->next = r; //然后整体右移 r = s; s = t; t = t->next; } s->next = r; l2->next->next = NULL;//逆置后链表尾部为NULL l2->next = s; } //三指针合并链表 void merge(LinkList l, LinkList l2) { LinkList pcur, p, q; pcur = l->next;//指向新链表的表尾 p = pcur->next; q = l2->next;//p,q用来遍历两条原链表 while (p && q) { pcur->next = q; q = q->next; pcur = pcur->next; pcur->next = p; p = p->next; pcur = pcur->next; } if (p) { pcur->next = p; } if (q) { pcur->next = q; } } int main() { LinkList l; LinkList l2;//存储第二条单链表头节点 tailList(l); findMiddle(l, l2); reverseList(l2); merge(l, l2); free(l2); printList(l); return 0; }