思路:
(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;//逆置后链表尾部为NULLl2->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; }