9.单链表反转
1定义
单链表node的数据结构定义如下:
class Node { // 注:此处的两个成员变量权限不能为private,因为private的权限是仅对本类访问 int data;// 数据域 Node next;// 指针域 public Node(int data) { this.data = data; } public int getData() { return data; } public void setData(int data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } }
2 方法1:就地反转法
2.1 思路
把当前链表的下一个节点pCur插入到头结点dummy的下一个节点中,就地反转。
dummy->1->2->3->4->5的就地反转过程:
dummy->2->1->3->4->5dummy->3->2->1->4->5dummy->4>-3->2->1->5dummy->5->4->3->2->12.2 解释
1初始状态
2 过程
pCur是需要反转的节点。
- prev连接下一次需要反转的节点
- 反转节点pCur
- 纠正头结点dummy的指向
- pCur指向下一次要反转的节点
伪代码
1 prev.next = pCur.next; 2 pCur.next = dummy.next; 3 dummy.next = pCur; 4 pCur = prev.next;
3 循环条件
pCur is not null
2.3 代码
// 1.就地反转法 public Node reverseList1(Node head) { if (head == null) return head; Node dummy = new Node(-1); dummy.next = head; Node prev = dummy.next; Node pCur = prev.next; while (pCur != null) { prev.next = pCur.next; pCur.next = dummy.next; dummy.next = pCur; pCur = prev.next; } return dummy.next; }
2.4 总结
- 1个头结点,2个指针,4行代码
- 注意初始状态和结束状态,体会中间的图解过程。
3 方法2:新建链表,头节点插入法
3.1 思路
新建一个头结点,遍历原链表,把每个节点用头结点插入到新建链表中。最后,新建的链表就是反转后的链表。
3.2 解释
1 初始状态
2 过程
pCur是要插入到新链表的节点。
pNex是临时保存的pCur的next。
- pNex保存下一次要插入的节点
- 把pCur插入到dummy中
- 纠正头结点dummy的指向
- pCur指向下一次要插入的节点
伪代码
1 pNex = pCur.next 2 pCur.next = dummy.next 3 dummy.next = pCur 4 pCur = pNex
3 循环条件
pCur is not null
3.3 代码
// 2.新建链表,头节点插入法 public Node reverseList2(Node head) { Node dummy = new Node(-1); Node pCur = head; while (pCur != null) { Node pNex = pCur.next; pCur.next = dummy.next; dummy.next = pCur; pCur = pNex; } return dummy.next; }
3.4 总结
- 1个头结点,2个指针(包含一个临时保存节点的pNex),4行代码
- 注意初始状态和结束状态,体会中间的图解过程。
测试代码:
LinkList list4 = new LinkList(); for (int i = 5; i < 10; i++) { list4.add(i); } LinkList list5 = new LinkList(); list5.head = list4.reverseList2(list4.head); System.out.print("反转后的链表为:"); System.out.print("\r\n"); list5.print(list5.head);// 从head节点开始遍历输出
结果:
反转后的链表为:
9
8
7
6
5
转自:http://www.cnblogs.com/byrhuangqiang/p/4311336.html