算法整理-单链表相关
来源:互联网 发布:linux注释#作用 编辑:程序博客网 时间:2024/06/16 08:42
参考连接思路,从头到尾实现了链表的相关操作。[http://blog.csdn.net/fightforyourdream/article/details/16843303]
通过集中式的训练,对于链表类题目有了比较系统的认识和理解,很有帮助,便于以后巩固复习,后边几个例子没有进行测试。。
package com.xpn.linklist;import java.awt.HeadlessException;import java.util.HashMap;import java.util.Stack;/** * http://blog.csdn.net/luckyxiaoqiang/article/details/7393134 轻松搞定面试中的链表题目 * http://www.cnblogs.com/jax/archive/2009/12/11/1621504.html 算法大全(1)单链表 * * 目录: * 1. 求单链表中结点的个数: getListLength * 2. 将单链表反转: reverseList(遍历),reverseListRec(递归) * 3. 查找单链表中的倒数第K个结点(k > 0): reGetKthNode * 4. 查找单链表的中间结点: getMiddleNode * 5. 从尾到头打印单链表: reversePrintListStack,reversePrintListRec(递归) * 6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList, mergeSortedListRec * 7. 判断一个单链表中是否有环: hasCycle * 8. 判断两个单链表是否相交: isIntersect * 9. 求两个单链表相交的第一个节点: getFirstCommonNode * 10. 已知一个单链表中存在环,求进入环中的第一个节点: getFirstNodeInCycle, getFirstNodeInCycleHashMap * 11. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted: delete * */ public class Main { private static class Node { int val; Node next; public Node(int val) { this.val = val; } } /** * @param args */ public static void main(String[] args) { Node n1 = new Node(1); Node n2 = new Node(2); Node n3 = new Node(3); Node n4 = new Node(4); Node n5 = new Node(5); n1.next = n2; n2.next = n3; n3.next = n4; n4.next = n5; printList(n1); Node n21 = new Node(1); Node n22 = new Node(2); Node n23 = new Node(3); Node n24 = new Node(4); Node n25 = new Node(5); n21.next = n22; n22.next = n23; n23.next = n24; n24.next = n25; //printList(getMiddleNode(n1)); printList(mergeSortedListRec(n1,n21)); System.out.println(); /*reversePrintListRec(n1); reversePrintListStack(n1);*/ } //1. 求单链表中结点的个数: getListLength private static int getListLength(Node head) { int len=0; Node cur=head; while(cur!=null){ len++; cur=cur.next; } return len; } private static void printList(Node head) { while(head!=null){ System.out.print(head.val+ " "); head=head.next; } System.out.println(); } //2. 将单链表反转: reverseList(遍历),reverseListRec(递归) private static Node reverseList(Node head) { if(head==null||head.next==null) return head; Node pre=new Node(0);//保存前面已经逆序的节点 Node cur=head;//当前节点 Node tmp=null;//保存当前节点的下一个节点 while(cur!=null){ tmp=cur.next; cur.next=pre; pre=cur; cur=tmp; } head.next=null; return pre; } private static Node reverseListRec(Node head) { if(head==null||head.next==null) return head; Node rehead =reverseList(head.next); head.next.next=head; head.next=null; return rehead; } //3. 查找单链表中的倒数第K个结点(k > 0): reGetKthNode private static Node reGetKthNode(Node head,int k){ if(head==null||k<=0) return null; Node slow=head; Node fast=head; while(0<k--){ if(fast==null) return null; fast=fast.next; } while(fast!=null){ fast=fast.next; slow=slow.next; } return slow; } //4. 查找单链表的中间结点: getMiddleNode private static Node getMiddleNode(Node head) { if(head==null||head.next==null||head.next.next==null) return head; Node slow=head; Node fast=head; while(fast.next!=null&&fast.next.next!=null){ fast=fast.next.next; slow=slow.next; } return slow; } //5. 从尾到头打印单链表: reversePrintListStack,reversePrintListRec(递归) private static void reversePrintListStack(Node head){ if(head==null) return; Stack<Node> stacks=new Stack<Node>(); Node cur=head; while (cur!=null) { stacks.push(cur); cur=cur.next; } while(!stacks.empty()){ System.out.print(stacks.pop().val+" "); } System.out.println(); } private static void reversePrintListRec(Node head){ if(head==null) return; reversePrintListRec(head.next); System.out.print(head.val+" "); } //6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList, mergeSortedListRec private static Node mergeSortedList(Node pHead1,Node pHead2) { if(pHead1==null) return pHead2; if(pHead2==null){ return pHead1; } Node dummy=new Node(0); Node cur=dummy;//保存整合的链表 Node p1=pHead1; Node p2=pHead2; while(p1!=null&&p2!=null){ if(p1.val<p2.val){ cur.next=p1; p1=p1.next; }else { cur.next=p2; p2=p2.next; } cur=cur.next; } if(p1!=null){ cur.next=p1; } if(p2!=null){ cur.next=p2; } return dummy.next; } private static Node mergeSortedListRec(Node pHead1,Node pHead2) { if(pHead1==null) return pHead2; if(pHead2==null) return pHead1; Node dummy=new Node(0); if(pHead1.val>pHead2.val){ dummy.next=pHead2; pHead2.next=mergeSortedListRec(pHead1, pHead2.next);; }else { dummy.next=pHead1; pHead1.next=mergeSortedListRec(pHead1.next, pHead2);; } return dummy.next; } //7. 判断一个单链表中是否有环: hasCycle private static boolean hasCycle(Node head){ if(head==null||head.next==null||head.next.next==null) return false; Node slow=head; Node fast=head; while(fast!=null&&fast.next!=null){ if(fast==slow){ return true; } slow=slow.next; fast=fast.next.next; } return false; } //8. 判断两个单链表是否相交: isIntersect 思路:最后一个必定相交 private static boolean isIntersect(Node head1,Node head2){ if(head1==null||head2==null) return false; while(head1.next!=null){ head1=head1.next; } while (head2.next!=null) { head2=head2.next; } if(head1==head2){ return true; } return false; } //9. 求两个单链表相交的第一个节点: getFirstCommonNode,思路:计算长度, private static Node getFirstCommonNode(Node head1,Node head2){ if(head1==null||head2==null) return null; int len1=0; Node tail1=head1; while(tail1!=null){ tail1=tail1.next; len1++; } int len2=0; Node tail2=head2; while(tail2!=null){ tail2=tail2.next; len2++; } if(tail1!=tail2){//不相交的情况 return null; } int k; if(len1>len2){ k=len2-len1; while(0<k--){ head1=head1.next; } }else { k=len1-len2; while(0<k--){ head2=head2.next; } } while(head1!=head2){ head1=head1.next; head2=head2.next; } return head1; } //10. 已知一个单链表中存在环,求进入环中的第一个节点: getFirstNodeInCycle, getFirstNodeInCycleHashMap private static Node getFirstNodeInCycle(Node head){ Node slow=head; Node fast=head; while(slow!=fast){ if(slow==null||fast.next==null) return null; slow=slow.next; fast=fast.next.next; } Node p1=head; while(p1!=slow){ p1=p1.next; slow=slow.next; } return p1; } private static Node getFirstNodeInCycleHashMap(Node head){ HashMap<Node, Boolean> maps=new HashMap<Node, Boolean>(); Node cur=head; while(cur!=null){ if(maps.get(cur)){ return cur; } maps.put(cur, true); cur=cur.next; } return null; } //11. 给出一单链表头指针pHead和一节点指针pToBeDeleted,O(1)时间复杂度删除节点pToBeDeleted: delete //变换思路,交换值,然后删除 private static void delete(Node head,Node pToBeDeleted){ if(head==null||pToBeDeleted==null){ return; } if(pToBeDeleted.next==null){ //遍历 Node dummy=new Node(0); Node pre=dummy; pre.next=head; while(pre.next!=pToBeDeleted){ pre=pre.next; } pre.next=pToBeDeleted.next; head=dummy.next; }else { Node tmpNode=pToBeDeleted.next; pToBeDeleted.val=tmpNode.val; pToBeDeleted.next=tmpNode.next; } }}
0 0
- 算法整理-单链表相关
- 相关算法学习资源整理
- 字符串相关的算法整理
- 常用算法整理:链表相关
- 常用算法整理:链表相关
- 一篇整理比较好的算法相关文章 Java语言
- 个人整理的机器学习/数据挖掘相关算法
- 一篇整理比较好的算法相关文章 Java语言
- 单链表相关算法
- 单链表相关算法
- 单链表的相关算法
- 算法整理
- 算法整理
- 算法整理
- 算法整理
- 算法整理
- 表单相关特效整理
- 表单相关特效整理
- 移动端页面编写摘记
- Chapter10 Querying with LINQ
- activity启动模式分析launchemode
- c# 之HttpContext通过表单提交后批量转换为Model
- 2015年创业中遇到的技术问题:71-80
- 算法整理-单链表相关
- Poj-3420 Quad Tiling
- 6/6plus适配的问题
- Edit Distance -- leetcode
- 内地艺人刘雨欣气质高清杂志图片
- HOF特征
- VS2008中Run-Time Check Failure#2 - Stack around the variable * was corrupted
- ZOJ 3326 - An Awful Problem
- Thread的一些基本操作