16-2 单链表从位置n到位置m的翻转

一、问题描述

反转从位置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;
}


梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值