一、问题描述
反转从位置m到n的链接列表。 在原地进行并一次完成。
例如:给定1-> 2-> 3-> 4-> 5> nullptr,m = 2和n = 4,
返回1-> 4-> 3-> 2-> 5> nullptr。
注意:给定m,n满足以下条件:1 <= m <= n <=列表长度
二、解题思路
1)找到待翻转的m和n位置,将m~n子单链表直接实现箭头逆转,
2)用3个指针分别记录逆转前m-1和n+1的位置以及子单链表第一个元素的位置
3)更改翻转后m~n子单链表的首尾指向,补全并恢复整个单链表
三、解题算法
/*****************************************************
Author:tmw
Date:2018-4-13
*****************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct Listnode
{
int data;
struct Listnode* next;
}Listnode;
/**实现单链表从位置m到位置n的翻转**/
Listnode* reverse_link_list( Listnode* L, int m, int n )
{
if( !L )
return NULL;
/**
思路:
1)找到待翻转的m和n位置,将m~n子单链表直接实现箭头逆转,
2)用3个指针分别记录逆转前m-1和n+1的位置以及子单链表第一个元素的位置
3)更改翻转后m~n子单链表的首尾指向,补全并恢复整个单链表
**/
/**这三个指针用于m~n子单链表的翻转**/
Listnode* cur,prev,next;
/**这三个指针分别记录逆转前m-1和n+1的位置以及子单链表第一个元素的位置**/
Listnode* pre_left, rear_right, prev_mark;
prev = L->next;
if(m==n&&m==1) /**只有一个元素的情况**/
return L;
cur = prev->next;
if( m = n-1 && m=1 ) /**只有两个元素且只需翻转两个**/
{
cur->next = prev;
prev->next = NULL;
return cur;
}
next = cur->next;
int i=0;
pre_left = L->next;
/**记录m-1的位置**/
for( i=1;i<m-1;i++ )
pre_left = pre_left->next;
pre_left = pre_left->next;
for( i=1; i<m; i++ )
{
cur = cur->next;
prev->next = cur;
cur->next = next;
}/**经过此for循环后,prev cur next三个游标位置已经准备就绪**/
/**记录prev移动前的位置**/
prev_mark = prev;
/**找第n+1的位置,并用指针记录**/
rear_right = prev;
for( i=1;i<n;i++ )
rear_right = rear_right->next;
rear_right = rear_right->next;
/**对m~n子单链表进行直接翻转---箭头反转即可**/
count = m;
while( count<n )
{
cur->next = prev;
prev = cur;
cur = next;
next = cur->next;
count++;
}
/**最后一步:更改翻转后m~n子单链表的首尾指向,补全并恢复整个单链表**/
/**接尾**/
prev_mark->next = rear_right;
/**接首**/
pre_left = next;
return L;
}
梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~~