算法整理-单链表相关

来源:互联网 发布: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
原创粉丝点击