赞
踩
题目:原链表中的数据为:0–>1–>2–>3–>4
反转后链表中数据为:4–>3–>2–>1–>0
递归反转其实就是从原链表的第一个存数据的结点开始,依次递归调用反转每一个结点,直到把最后一个结点反转完毕,整个链表就反转完毕。
代码实现:
import java.util.Iterator; /** * @author JIN * @description 单向链表 **/ public class LinkList<T> implements Iterable<T>{ private Node head;//头节点 private int N;//记录链表个数 private class Node{ //node节点 内部类 T data; Node next; public Node(T data, Node next){ this.data = data; this.next = next; } } //构造函数,初始化头节点,将链表个数记为0 public LinkList(){ head = new Node(null,null); N = 0; } //插入,尾插法 public void insert(T t){ Node node = head; while(node.next != null){ node = node.next; } node.next = new Node(t,null); N++; } //反转方法 public void reverse(){ //若链表为空,或者只有一个节点,不用反转,直接返回 if(N == 0 || N == 1){ return; } //调用反转方法 reverse(head.next); } private Node reverse(Node cur){ //递归的边界条件,当当前节点没有下一个节点即结束 if(cur.next == null){ head.next = cur; return cur; } //若当前节点有下一个节点,需先反转下一个节点。 //且接收上一个已经反转好的节点 Node pre = reverse(cur.next); pre.next = cur; cur.next = null; return cur; } //下面就是为了实现foreach功能,不是重点 @Override public Iterator iterator() { return new ILinkList(); } private class ILinkList implements Iterator{ private Node node; public ILinkList(){ node = head; } @Override public boolean hasNext() { return node.next != null; } @Override public Object next() { node = node.next; return node.data; } } public static void main(String[] args) { LinkList<Integer> list = new LinkList<>(); list.insert(0); list.insert(1); list.insert(2); list.insert(3); list.insert(4); for (Integer i: list) { System.out.print(i + " "); } System.out.println(); System.out.println("--------------"); list.reverse(); for (Integer i: list) { System.out.print(i + " "); } } }
图画解释:
我们反转只需要将节点的next指向反过来即可。由图可知,我们需要先反转最后一个节点,再继续反转倒数第二个节点,依次类推。为什么呢?就如上图来说,如果你先反转了节点1的话,你将再也找不到节点2了,因此,我们只能先反转后面的,然后再反转自身,这样子就完成整个的反转。
代码如下(其他部分代码跟上面一致):
public void reverse(){ //若链表为空,或者只有一个节点,无需反转,直接返回 if(N == 0 || N == 1){ return; } //定义三个Node节点,分别来记录节点信息。 Node temp = null; //由于我这链表有头节点,因此移动到当前需要的节点上。 Node cur = head.next; Node pre = cur; while(cur.next != null){ cur = cur.next; pre.next = temp; temp = pre; pre = cur; } //退出循环后,把最后一个节点,跟头节点设置好即可 pre.next = temp; head.next = pre; }
原理
图像解析:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。