链表逆序
Posted 妙啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了链表逆序相关的知识,希望对你有一定的参考价值。
Leedcode 206 链表逆序I
从头逆序
图解步骤
备份head.next(原下一节点),修改head.next指向新头,移动修改两链表的头指针(新指向新的节点(原头节点),原再指向下一节点[备份点])
- 迭代法
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode curr=head;
ListNode newHead=null;
while(curr!=null){
//备份next
ListNode bak=curr.next;
//修改next指向,既将head与newHead连接
curr.next=newHead;
//移动head和newHead
newHead=curr;
curr=bak;
}
return newHead;
}
}
- 递归法
public ListNode reverseList(ListNode head) {
//递归到最下一层获得末尾节点
if (head == null || head.next == null) return head;
//每次递归完成后head都会往前移位
ListNode p = reverseList(head.next);
//head.next既当前节点(5),将其下一节点指向前一节点(4)
head.next.next = head;
//将前一节点(4)指向null
head.next = null;
//返回固定节点(5)
return p;
}
LeedCode 92 链表逆序II
部分逆序
图解步骤
-
迭代法
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { //需要逆置的节点数 int len=n-m+1; //备份原始头节点 ListNode result=head; ListNode pre_head=null; //找到开始逆置节点 for(int k=1;k<m;k++){ //找到逆置节点前节点 pre_head=head; head=head.next; } //设置new_head ListNode new_head=head; //备份更改后的尾节点 ListNode modify_tail=head; //逆置begin for(int num=0;num<len;num++){ //备份head的下节点 ListNode bak_next=head.next; //下节点指向新头 head.next=new_head; //新头向前移 new_head=head; //原头后移 head=bak_next; } //将后置节点连上 modify_tail.next=head; //将前驱节点连上 if(pre_head!=null) pre_head.next=new_head; else result=new_head; //若从头节点逆置,返回值应该为新头节点 //返回原始头 return result; } }
-
递归换值法
class Solution { private boolean stop; private ListNode left; public ListNode reverseBetween(ListNode head,int m,int n){ this.left=head; this.stop=false; this.recurseAndReverse(head,m,n); //最上层的还是head节点,直接返回head return head; } /** *function:递归到最下层并进行一次交换 *tips:每次的最右节点都是回溯的 */ public void recurseAndReverse(ListNode right,int m,int n){ //如果右到底,结束递归 if(n==1) return; //为了找到右节点 right=right.next; //为了找到左节点 if(m>1){ this.left=this.left.next; } //递归获得最左及最右节点 recurseAndReverse(right,m-1,n-1); //递归后的每一次都从这里开始交换 //定义暂停条件 if(this.left==right||this.left==right.next){ this.stop=true; } if(!this.stop){ //交换值 int temp=this.left.val; this.left.val=right.val; right.val=temp; //左就向右移动一位 //右通过回溯左移一位 this.left=this.left.next; } } }
以上是关于链表逆序的主要内容,如果未能解决你的问题,请参考以下文章
设计鲁棒性的方法:输入一个链表的头结点,逆序遍历打印该链表出来