- 反转链表 2024.8.9
- 用到pre和next两个节点,pre用作当前节点往前指向的上一个节点,因为节点要指向前一个结点,断裂之后失去后一个结点的信息,因此当前节点改变指向前要保存下一个节点的信息,next就是用来保存下一个节点。
- 返回头指针即意味着返回整个链表。
public ListNode ReverseList(ListNode head) {
ListNode pre=null;
ListNode next=null;
while(head!=null){
next = head.next;//先保存下一个节点
head.next = pre;//当前节点的next指向前一个节点
pre = head;//前一个节点后移
head = next;//当前节点后移
}
return pre;} //pre成为头节点,返回它即可。
关于链表:
- 头节点为第一个节点之前的节点,其为空节点不含数据(有时也用来存储链表的长度)。
- 头指针为所有节点之前的指针,当设置了头节点时,其指向头节点,不设头节点时,其指向正常的第一个节点。指针即为地址,头指针存放着首个节点的地址。
- 头节点不一定存在而头指针一定存在。
-
指定区间内反转链表
输入:{1,2,3,4,5},2,4 返回值:{1,4,3,2,5}
解1:
-
设置虚拟头节点
ListNode dummyNode =new ListNode(-1)
dummyNode.next=head; -
start节点和end节点=head,循环.next找到要求反转部分的前后,将其前节点next指向空,反转部分尾元素也指向空,即将要反转的部分与原链表断开,反转部分的第一个节点start,最后一个节点end,则将这两个节点的前后保存下来如prestart,endnext。
-
将要反转部分的第一个节点传入反转函数-基本为第一题,将prestart.next=endnext,即指向反转后的第一个元素。
start.next=endnext;即反转后的尾元素指向保存的后节点。
-
返回头节点的next即可
解1的遍历次数过多。解法2:区间内每遍历到节点,就让新节点来到反转的起始位置
public ListNode reverseBetween (ListNode head, int m, int n) { ListNode dum = new ListNode(0); dum.next = head; //设置虚拟头节点 ListNode pre = dum; for(int i = 1; i < m; i++){ pre = pre.next; // 找到m的上一个节点,即反转的前点。 } head = pre.next; // 从m的位置开始进行交换 ListNode next; // 用于暂存遍历节点的后继节点 for(int i = m; i < n; i++){ // 0.暂存遍历节点的下一个节点 next = head.next; // 1.让当前节点指向 后继节点的后继节点 head.next = next.next; // 2.让后继节点指向反转元素的首位-新节点来到反转的起始位置 next.next = pre.next; // 3.让反转前点 指向 此后继节点 pre.next = next; } return dum.next; }
-
- 第一步,节点2指向4,2-5之间断开。
- 第二步,节点5指向2,5-4之间断开。
- 第三步,反转前点指向节点5,节点5成为首位节点。9-7-5-2-4-3-6