算法题:单链表反转
题目解析:
单链表
A.next->B
B.next->C
C.next->D
D.next->E
A->B->C->D->E
反转后
E->D->C->B->A
手动反转
1、B.next=A
2、C.next=B
3、D.next=C
4、E.next=D
5、A.next=null
6、返回E
由于对象的next被设置后会丢失原来的指向,难以继续往后遍历替换。
所以想到的方式是递归,即
A、B交换->B、C交换->C、D交换->D、E交换;
终止条件是交换行为中的第二个节点的next为空
然后清除掉原来头节点的next指向
一、先尝试for、while循环,发现不好写出来,感觉更像递归,因为递归会取到内存(所以递归写法内存占用会高)
二、确定用递归写之后,要先找到递归终止条件。从实际的手推例子,认为第二个节点的next为空是终止条件
三、需要清除掉原来头节点的next指向,必须返回原来的尾部节点
static class Node { private final String name; private Node next; public Node(String name, Node next) { this.name = name; this.next = next; } } public static void main(String[] args) { Node root = new Node("A", new Node("B", new Node("C", new Node("D", new Node("E", null))))); // A->B->C->D->E // B.next=A // C.next=B // D.next=C // E.next=D Node node = swap(root); root.next = null; do { System.out.println(node.name); } while ((node = node.next) != null); } public static Node swap(Node a) { if (a == null || a.next == null) { return a; } Node swap = swap(a.next); a.next.next = a; a.next = null; return swap; }
非递归写法
static class Node { private final String name; private Node next; public Node(String name, Node next) { this.name = name; this.next = next; } } public static void main(String[] args) { Node root = new Node("A", new Node("B", new Node("C", new Node("D", new Node("E", null))))); // A->B->C->D->E // B.next=A // C.next=B // D.next=C // E.next=D Node pre = null; Node cur = root; Node next; while (cur != null) { next = cur.next; cur.next = pre; pre = cur; cur = next; } do { System.out.println(pre.name); } while ((pre = pre.next) != null); }