面经------单向链表反转

版权声明:版权归博主CodingArtist所有,转载请标明出处。 https://blog.csdn.net/sc19951007/article/details/83613598

面经------单向链表反转

问题描述

现定义了如下的ListNode结构, 要求对整个List进行反转。

//Definition for singly-linked list.
public class ListNode {
      int val;
      ListNode next;
      ListNode(int x) { val = x; }
}

递归解法

递归的思路是从链表的最后一个Node开始反转,创建一个newHead指向最后一个Node(cur),head指向newHead的前一个Node, 然后反转cur和head,如此逐步向前。

详细解释如下。

首先指针H迭代到底如下图所示,并且设置一个新的指针newHead作为反转后的链表的头。由于整个链表翻转之后的头就是最后一个数,所以整个过程newHead指针一直指向最后一个Node。

然后H指针逐层返回的时候如下图,将H指向的地址赋值给nextNode->next指针,并且一定要记得让H->next =NULL,也就是断开现在指针的链接,否则新的链表形成了环,下一层nextNode->next赋值的时候会覆盖后续的值。程序中的nextNode指针即为上一层返回的H->next.

第二次返回nextNode后如下图。

逐层返回:

返回到头后如下图:

代码如下:

public ListNode reverseList(ListNode head) {
        if(head == null || head.next == null)
            return head;
        ListNode nextNode = head.next;
        ListNode newHead = reverseList(nextNode);
        nextNode.next = head;
        head.next = null;
        return newHead;
        }

非递归解法

非递归的方法与递归方法相反,它是从前往后顺序处理Node的。

首先设置两个新Node,P (curr)和 newH(prev)。

然后依次将旧链表上每一项添加在新链表的后面,然后新链表的头指针NewH移向新的链表头,如下图所示。此处需要注意,不可以上来立即将上图中P->next直接指向NewH,这样存放2的地址就会被丢弃,后续链表保存的数据也随之无法访问。而是应该设置一个临时指针nextTemp,先暂时指向P->next指向的地址空间,保存原链表后续数据。然后再让P->next指向NewH,最后P=nextTemp就可以取回原链表的数据了,所有循环访问也可以继续展开下去

指针继续向后移动,直到P指针指向NULL停止迭代。

最后一步

代码如下:

public ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode nextTemp = curr.next;
        curr.next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}

仅用于个人的学习理解,如需转载,请标明出处:
https://blog.csdn.net/sc19951007/article/details/83613598

猜你喜欢

转载自blog.csdn.net/sc19951007/article/details/83613598