# 题目:
* 1、从尾到头打印链表
* 2、链表中倒数第K个节点
* 3、反转链表
* 4、合并两个排序的链表
* 5、复杂链表的复制
* 6、两个链表的第一个公共结点
* 7、孩子们的游戏(模拟)
* 8、链表中环的入口(两种方法)
* 9、链表 3个 3个反转。 abcdef -> cba fed ??????
### 1、从尾到头打印链表
方法1:用栈
方法2:递归
方法3:反转链表,从头输出。
ListNode* pro=NULL; 新建首尾
ListNode* next=NULL;
while(head!=NULL){
next=head->next; 尾指下一个
head->next=pro; 断开,当前指向pro
pro=head; pro ,当前都后移
head=next;
}

-
ListNode* reverse(ListNode* H) {
-
//包括特殊情况
-
if (H == NULL || H->next == NULL)
-
return H;
-
-
ListNode *newH = reverse(H->next);//注意,此处的操作是一直循环到链表末尾
-
H->next->next = H;//反转每个节点的指向
-
H->next = NULL;
-
-
return newH;
-
}
### 2、链表中倒数第K个节点
双指针,一个先走K个,另一个再开始走。
### 3、反转链表
### 4、合并两个排序的链表
```c++
node* merge(node* head1,node* head2){
if(head1===NULL)
return head2;
if(head2==NULL)
return head1;
node* res=new node(0);
node* p=res;
while(head1&&head2){
if(head1->val<=head2->val){
res=head1;
head1=head1->next;
}
else{
res=head2;
head2=head2->next;
}
}
if(head1)
res=head1;
if(head2)
res=head2;
}
```
递归
/*Using Recursion*/
struct node* SortedMerge(struct node* a, struct node* b)
{
struct node* result = NULL;
/*Base cases*/
if(a == NULL)
return (b);
else if(b == NULL)
return (a);
/*Pick either a or b, and recur */
if(a->data <= b->data)
{
result = a;
result->next = SortedMerge(a->next, b);
}
else
{
result = b;
result->next = SortedMerge(a, b->next);
}
return (result);
}
### 5、复杂链表的复制
### 6、两个链表的第一个公共结点
##### 题目 含义:
* 一定有公共结点 (不存在 = 型)
* 公共节点后,一定重合, Y字型 (不可能是 V 字型,开头重合 ,后面分开的情况)
* 思路:长的 先走 两个长度差,后面一起走,并判断 指针是否相同。
特例: 两个链表完全重合。
### 7、孩子们的游戏(模拟)
f(n)=(f(n-1)+m)%n
n个人 连续 报数 报m 的踢出去,
### 8、链表中环的入口
快慢指针:(追及问题)
一圈长度固定,快指针速度是 慢指针的t倍,追及相遇点也就是 快指针转t圈以后的位置。(拓展,没啥用)
##### 方法一:(对大数据,环特别长的时候有弊端)
* 解决这个问题可以分三步。
* (1) 快慢指针看是否相遇,判断是否有环。
* (2) 计算环节点长度,慢指针继续走,同时计数,再次到达快指针所在位置停止计数
* (3)两个指针从头开始,一个先走 环长步数,之后两个一起走(同时判断指针是否相同),第一次相同则为环的入口。
##### 方法二:
* (1) 快慢指针看是否相遇,判断是否有环。
* (2) 规律: 相遇点到环入口距离+n倍的(环长)==相同起始点到环入口距离。 (编程不考虑n倍,走多少圈结果相同)