链表反转的四种方法分析
2015-06-11 21:59
323 查看
关于反转链表的总结:
反转链表的方式有很多,现在介绍四种:
非递归的:
从图中可以看到,对n个节点的反转,方法一指针指向改变了2^(n-1)次,还有一个额外的节点,而方法二用了2^(n-1)次,却没有增加额外节点。方法三既没有增加新节点,指针指向改变了n次,显然方法三好。
递归方法很赞,图就不好画了,大家直接看代码。
代码:
反转链表的方式有很多,现在介绍四种:
非递归的:
从图中可以看到,对n个节点的反转,方法一指针指向改变了2^(n-1)次,还有一个额外的节点,而方法二用了2^(n-1)次,却没有增加额外节点。方法三既没有增加新节点,指针指向改变了n次,显然方法三好。
递归方法很赞,图就不好画了,大家直接看代码。
代码:
package OfferTest; import java.util.HashMap; /** * class ListNode * @author cyc * */ public class ListNode { int val; ListNode next; ListNode(int x){ val = x; } /** * print List from its head node * @param head */ public static void printList(ListNode head){ HashMap<ListNode, Boolean> hm = new HashMap<ListNode, Boolean>(); ListNode mv = head; while(mv!=null){ if(!hm.containsKey(mv)){ System.out.print(mv.val+"——>"); hm.put(mv, true); mv = mv.next; } else{ System.out.print(mv.val+" is the circle List\n"); return; } } System.out.print("null\n"); } /** * Transfer int[] array to List * @param array * @return ListNode */ public static ListNode arrayToList(int[] array){ if(array.length==0){ return null; } else{ ListNode head = new ListNode(array[0]); ListNode end = head; for(int i=1; i<array.length; i++){ ListNode tmpNode = new ListNode(array[i]); end.next = tmpNode; end = end.next; } end.next = null; return head; } } }
package OfferTest; public class ReverseList { public static void main(String[] args) { int[] array = {1,2,3}; ListNode head = ListNode.arrayToList(array); ReverseList rl = new ReverseList(); head = rl.reverseList1(head); ListNode.printList(head); head = rl.reverseList2(head); ListNode.printList(head); head = rl.reverseList3(head); ListNode.printList(head); head = rl.recusionList(head); ListNode.printList(head); } /** * 增加节点法 * @param head * @return */ public ListNode reverseList1(ListNode head){ //增加一个新的节点newHead ListNode newHead = new ListNode(0); newHead.next = null; ListNode cur; while(head!=null){ cur = head; head = head.next; cur.next = newHead.next; newHead.next = cur; } return newHead.next; } /** * 反转两个节点的次序,需要指针移动两次 * @param head * @return */ public ListNode reverseList2(ListNode head){ if(head==null||head.next==null){ return head; } ListNode cur = head.next; ListNode end = head; while(cur!=null){ end.next = cur.next; cur.next = head; head = cur; cur = end.next; } return head; } /** * 反转两个节点时,移动一次指针 * @param head * @return */ public ListNode reverseList3(ListNode head){ if(head==null||head.next==null){ return head; } ListNode cur = head.next; ListNode tmp; head.next = null; while(cur!=null){ tmp = cur.next; cur.next = head; head = cur; cur = tmp; } return head; } /** * 递归解法 * @param head * @return */ public ListNode recusionList(ListNode head){ if(head==null||head.next==null){ return head; } ListNode nextHead = recusionList(head.next); head.next.next = head; head.next = null; return nextHead; } }
相关文章推荐
- [C/C++]反转链表
- C语言实现带头结点的链表的创建、查找、插入、删除操作
- asp.net中控制反转的理解(文字+代码)
- Linux内核链表实现过程
- C++链表倒序实现方法
- C#通过链表实现队列的方法
- 找出链表倒数第n个节点元素的二个方法
- Java数据结构之简单链表的定义与实现方法示例
- Java反转字符串和相关字符编码的问题解决
- C语言单循环链表的表示与实现实例详解
- php实现字符串反转输出的方法
- PHP小教程之实现链表
- C语言双向链表的表示与实现实例详解
- C语言实现输出链表中倒数第k个节点
- C++语言实现线性表之链表实例
- STL list链表的用法详细解析
- C语言创建链表错误之通过指针参数申请动态内存实例分析
- 编码实现从无序链表中移除重复项(C和JAVA实例)
- Java采用循环链表结构求解约瑟夫问题
- 链表集合