```/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param head ListNode类 
 * @param m int整型 
 * @param n int整型 
 * @return ListNode类
 */
struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {
    // write code here
    struct ListNode *The_M_p, *The_Mminus1_p; // 声明两个指针变量;一个是第m-1个结点,一个是m个结点;
    The_M_p = head; The_Mminus1_p = head; // 为什么要两个呢?因为改变链表后,结点地址自然也就改变1;
    for(int i = 1; i < m-1; i++) {  // 而最后要将改变的地址两端重新衔接上;
        The_Mminus1_p = The_Mminus1_p->next;
    }
    
    if(m != 1) The_M_p = The_Mminus1_p->next; // 这里是若m == 1时的情况,m==1情况特殊;
    else The_M_p = head;                    // 我定义The_M_p 和 The_Mminus1_初始地址相同,均为head;
                                            // 所以m==1时,The_M_p也应该等于head;    
    struct ListNode *The_N_p, *The_Nadd1_p; // 第n个值同理,只不过,这时是第n个 和 第n+1 个,
    The_N_p = head; The_Nadd1_p = head;  // 不过我这个程序不用while语句,所以只用第n+1个, 用来衔接;
    for(int i = 1; i < n; i++) {
        The_N_p = The_N_p->next;
    }
    // m to n 逆序;用无头结点的头插法即可;
    The_Nadd1_p = The_N_p->next;
    struct ListNode *q, *p, *record;
    record = The_M_p;// 记录第m个结点的地址;地址地址地址,//狭义的理解:结点的地址不会改变;
    q = The_M_p;
    for(int i = m-1; i < n; i++) { // Notice: 这个是循环(n-m+1)次,因为刚开始是自身交换哦//(
        q = The_M_p;
        The_M_p = The_M_p->next;
        q->next = p;// 头插法 //核心代码
        p = q;      // 头插法 //核心代码
    }
    if(m == 1) {  // m == 1 是个特殊的情况;
        head = p;  // 因为m == 1时,The_M_p == The_Mminus1_p == record == 首元结点的地址;
    } else {
        The_Mminus1_p->next = p;
    }
    record->next = The_Nadd1_p;
    return head;
}

/*
 {1,2,3,4,5} 2,4;
 1 -> 2 -> 3 -> 4 ->5;
 //head.val = 1;
 //The_Mminus1_p.val = 1;
 //The_Nadd1_p.val = 5;
 交换2 -> 3 -> 4; Notice: 1 -> 2  & 4 -> 5哦;
 头插法交换完后:|----未知(因为没有给分配,详见line36)
 1   4 -> 3 -> 2   5
 |-------------|(1 -> 2;
 所以这时要把m 和n处衔接上;
 就是line45 to line50;
 
 {1,2,3,4,5} 1,3;
 这个例子特殊,
 因为m == 1;
 可以自己推一下试试;
 
 综上所述:我的题解就讲完了,第一次发题解,望见谅;;
*/