链表的操作和基本算法 java

原创 2016年08月29日 09:38:32
  1. import java.util.HashMap;  
  2. import java.util.Scanner;  
  3. import java.util.Stack;  
  4.   
  5. /** 
  6.  *  
  7.  * @author kerryfish 
  8.  * 关于java中链表的操作 
  9.  * 1. 求单链表中结点的个数: getListLength  
  10.  * 2. 将单链表反转: reverseList(遍历),reverseListRec(递归)  
  11.  * 3. 查找单链表中的倒数第K个结点(k > 0): reGetKthNode  
  12.  * 4. 查找单链表的中间结点: getMiddleNode  
  13.  * 5. 从尾到头打印单链表: reversePrintListStack,reversePrintListRec(递归)  
  14.  * 6. 已知两个单链表pHead1 和pHead2 各自有序,把它们合并成一个链表依然有序: mergeSortedList, mergeSortedListRec  
  15.  * 7. 对单链表进行排序,listSort(归并),insertionSortList(插入) 
  16.  * 8. 判断一个单链表中是否有环: hasCycle  
  17.  * 9. 判断两个单链表是否相交: isIntersect  
  18.  * 10. 已知一个单链表中存在环,求进入环中的第一个节点: getFirstNodeInCycle, getFirstNodeInCycleHashMap  
  19.  * 11. 给出一单链表头指针head和一节点指针delete,O(1)时间复杂度删除节点delete: deleteNode 
  20.  */  
  21. public class LinkedListSummary {  
  22.     /** 
  23.      * @param args 
  24.      *  
  25.      */  
  26.     public static class Node{  
  27.         int value;  
  28.         Node next;  
  29.         public Node(int n){  
  30.             this.value=n;  
  31.             this.next=null;  
  32.         }  
  33.     }  
  34.     public static void main(String[] args) {  
  35.         // TODO Auto-generated method stub  
  36.         Scanner in=new Scanner(System.in);  
  37.         Node head=null;  
  38.         if(in.hasNextInt()){  
  39.             head=new Node(in.nextInt());  
  40.         }  
  41.         Node temp=head;  
  42.         while(in.hasNextInt()){  
  43.             temp.next=new Node(in.nextInt());  
  44.             temp=temp.next;  
  45.         }  
  46.         in.close();  
  47.         //int len=getListLength(head);  
  48.         //Node reHead=reverseList(head);  
  49.         //reHead=reverseListRec(reHead);  
  50.         //Node node_k=reGetKthNode(head,3);  
  51.         //Node mid=getMiddleNode(head);  
  52.         //reversePrintListRec(head);  
  53.         //reversePrintListStack(head);  
  54.         //Node mergeHead=mergeSortedList(head,null);  
  55.         //Node sortHead=listSort(head);  
  56.           
  57.     }  
  58.     //求单链表中结点的个数: getListLength   
  59.     public static int getListLength(Node head){  
  60.         int len=0;  
  61.         while(head!=null){  
  62.             len++;  
  63.             head=head.next;  
  64.         }  
  65.         return len;  
  66.     }  
  67.     //将单链表反转,循环  
  68.     public static Node reverseList(Node head){  
  69.         if(head==null||head.next==null)return head;  
  70.         Node pre=null;  
  71.         Node nex=null;  
  72.         while(head!=null){  
  73.             nex=head.next;  
  74.             head.next=pre;  
  75.             pre=head;  
  76.             head=nex;  
  77.         }  
  78.         return pre;  
  79.     }  
  80.     //将单链表反转,递归  
  81.     public static Node reverseListRec(Node head){  
  82.         if(head==null||head.next==null)return head;  
  83.         Node reHead=reverseListRec(head.next);  
  84.         head.next.next=head;  
  85.         head.next=null;  
  86.         return reHead;  
  87.     }  
  88.     //查找单链表中的倒数第K个结点(k > 0)  
  89.     public static Node reGetKthNode(Node head,int k){  
  90.         if(head==null)return head;  
  91.         int len=getListLength(head);  
  92.         if(k>len)return null;  
  93.         Node target=head;  
  94.         Node nexk=head;  
  95.         for(int i=0;i<k;i++){  
  96.             nexk=nexk.next;  
  97.         }  
  98.         while(nexk!=null){  
  99.             target=target.next;  
  100.             nexk=nexk.next;  
  101.         }  
  102.         return target;  
  103.     }  
  104.     //查找单链表的中间结点   
  105.     public static Node getMiddleNode(Node head){  
  106.         if(head==null||head.next==null)return head;  
  107.         Node target=head;  
  108.         Node temp=head;  
  109.         while(temp!=null&&temp.next!=null){  
  110.             target=target.next;  
  111.             temp=temp.next.next;  
  112.         }  
  113.         return target;  
  114.     }  
  115.     //从尾到头打印单链表,递归  
  116.     public static void reversePrintListRec(Node head){  
  117.         if(head==null)return;  
  118.         else{  
  119.             reversePrintListRec(head.next);  
  120.             System.out.println(head.value);  
  121.         }  
  122.     }  
  123.     //从尾到头打印单链表,栈  
  124.     public static void reversePrintListStack(Node head){  
  125.         Stack<Node> s=new Stack<Node>();  
  126.         while(head!=null){  
  127.             s.push(head);  
  128.             head=head.next;  
  129.         }  
  130.         while(!s.isEmpty()){  
  131.             System.out.println(s.pop().value);  
  132.         }  
  133.     }  
  134.     //合并两个有序的单链表head1和head2,循环  
  135.     public static Node mergeSortedList(Node head1,Node head2){  
  136.         if(head1==null)return head2;  
  137.         if(head2==null)return head1;  
  138.         Node target=null;  
  139.         if(head1.value>head2.value){  
  140.             target=head2;  
  141.             head2=head2.next;  
  142.         }  
  143.         else{  
  144.             target=head1;  
  145.             head1=head1.next;  
  146.         }  
  147.         target.next=null;  
  148.         Node mergeHead=target;  
  149.         while(head1!=null && head2!=null){  
  150.             if(head1.value>head2.value){  
  151.                 target.next=head2;  
  152.                 head2=head2.next;  
  153.             }  
  154.             else{  
  155.                 target.next=head1;  
  156.                 head1=head1.next;  
  157.             }  
  158.             target=target.next;  
  159.             target.next=null;  
  160.         }  
  161.         if(head1==null)target.next=head2;  
  162.         else target.next=head1;  
  163.         return mergeHead;  
  164.     }  
  165.     //合并两个有序的单链表head1和head2,递归  
  166.     public static Node mergeSortedListRec(Node head1,Node head2){  
  167.         if(head1==null)return head2;  
  168.         if(head2==null)return head1;  
  169.         if(head1.value>head2.value){  
  170.             head2.next=mergeSortedListRec(head2.next,head1);  
  171.             return head2;  
  172.         }  
  173.         else{  
  174.             head1.next=mergeSortedListRec(head1.next,head2);  
  175.             return head1;  
  176.         }  
  177.     }  
  178.     //对单链表进行排序,归并排序,在排序里面不建议选用递归的合并有序链表算法,如果链表长度较长,很容易出现栈溢出  
  179.     public static Node listSort(Node head){  
  180.         Node nex=null;  
  181.         if(head==null||head.next==null)return head;  
  182.         else if(head.next.next==null){  
  183.             nex=head.next;  
  184.             head.next=null;  
  185.         }  
  186.         else{  
  187.             Node mid=getMiddleNode(head);  
  188.             nex=mid.next;  
  189.             mid.next=null;  
  190.         }  
  191.         return mergeSortedList(listSort(head),listSort(nex));//合并两个有序链表,不建议递归  
  192.     }  
  193.     //对单链表进行排序,插入排序  
  194.     public Node insertionSortList(Node head) {  
  195.         if(head==null||head.next==null)return head;  
  196.         Node pnex=head.next;  
  197.         Node pnex_nex=null;  
  198.         head.next=null;  
  199.         while(pnex!=null){  
  200.             pnex_nex=pnex.next;  
  201.             Node temp=head;  
  202.             Node temp_pre=null;  
  203.             while(temp!=null){  
  204.                 if(temp.value>pnex.value)break;  
  205.                 temp_pre=temp;  
  206.                 temp=temp.next;  
  207.             }  
  208.             if(temp_pre==null){  
  209.                 head=pnex;  
  210.                 pnex.next=temp;  
  211.             }  
  212.             else{  
  213.                 temp_pre.next=pnex;  
  214.                 pnex.next=temp;  
  215.             }  
  216.             pnex=pnex_nex;  
  217.         }  
  218.         return head;  
  219.     }  
  220.     //判断一个单链表中是否有环,快慢指针  
  221.     public static boolean hasCycle(Node head){  
  222.         boolean flag=false;  
  223.         Node p1=head;  
  224.         Node p2=head;  
  225.         while(p1!=null&&p2!=null){  
  226.             p1=p1.next;  
  227.             p2=p2.next.next;  
  228.             if(p2==p1){  
  229.                 flag=true;  
  230.                 break;  
  231.             }  
  232.         }  
  233.         return flag;  
  234.     }  
  235.     //判断两个单链表是否相交,如果相交返回第一个节点,否则返回null  
  236.     //如果单纯的判断是否相交,只需要看最后一个指针是否相等  
  237.     public static Node isIntersect(Node head1,Node head2){  
  238.         Node target=null;  
  239.         if(head1==null||head2==null)return target;  
  240.         int len1=getListLength(head1);  
  241.         int len2=getListLength(head2);  
  242.         if(len1>=len2){  
  243.             for(int i=0;i<len1-len2;i++){  
  244.                 head1=head1.next;  
  245.             }  
  246.         }else{  
  247.             for(int i=0;i<len2-len1;i++){  
  248.                 head2=head2.next;  
  249.             }  
  250.         }  
  251.         while(head1!=null&&head2!=null){  
  252.             if(head1==head2){  
  253.                 target=head1;  
  254.                 break;  
  255.             }  
  256.             else{  
  257.                 head1=head1.next;  
  258.                 head2=head2.next;  
  259.             }  
  260.         }  
  261.         return target;  
  262.     }  
  263.     //已知一个单链表中存在环,求进入环中的第一个节点,利用hashmap,不要用ArrayList,因为判断ArrayList是否包含某个元素的效率不高  
  264.     public static Node getFirstNodeInCycleHashMap(Node head){  
  265.         Node target=null;  
  266.         HashMap<Node,Boolean> map=new HashMap<Node,Boolean>();  
  267.         while(head!=null){  
  268.             if(map.containsKey(head))target=head;  
  269.             else{  
  270.                 map.put(head, true);  
  271.             }  
  272.             head=head.next;  
  273.         }  
  274.         return target;  
  275.     }  
  276.     //已知一个单链表中存在环,求进入环中的第一个节点,不用hashmap  
  277.     //用快慢指针,与判断一个单链表中是否有环一样,找到快慢指针第一次相交的节点,此时这个节点距离环开始节点的长度和链表投距离环开始的节点的长度相等  
  278.     public static Node getFirstNodeInCycle(Node head){  
  279.         Node fast=head;  
  280.         Node slow=head;  
  281.         while(fast!=null&&fast.next!=null){  
  282.             slow=slow.next;  
  283.             fast=fast.next.next;  
  284.             if(slow==fast)break;  
  285.         }  
  286.         if(fast==null||fast.next==null)return null;//判断是否包含环  
  287.         //相遇节点距离环开始节点的长度和链表投距离环开始的节点的长度相等  
  288.         slow=head;  
  289.         while(slow!=fast){  
  290.             slow=slow.next;  
  291.             fast=fast.next;  
  292.         }//同步走  
  293.         return slow;  
  294.           
  295.     }  
  296.     //给出一单链表头指针head和一节点指针delete,O(1)时间复杂度删除节点delete  
  297.     //可惜采用将delete节点value值与它下个节点的值互换的方法,但是如果delete是最后一个节点,则不行,但是总得复杂度还是O(1)  
  298.     public static void deleteNode(Node head,Node delete){  
  299.         //首先处理delete节点为最后一个节点的情况  
  300.         if(delete==null)return;  
  301.         if(delete.next==null){  
  302.             if(head==delete)head=null;  
  303.             else{  
  304.                 Node temp=head;  
  305.                 while(temp.next!=delete){  
  306.                     temp=temp.next;  
  307.                 }  
  308.                 temp.next=null;  
  309.             }  
  310.         }  
  311.         else{  
  312.             delete.value=delete.next.value;  
  313.             delete.next=delete.next.next;  
  314.         }  
  315.         return;  
  316.     }  
  317. }  
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

JAVA中关于链表的操作和基本算法

import java.util.HashMap; import java.util.Scanner; import java.util.Stack; /** * * @author Thin...

Java算法(链表操作实例)

  • 2012年10月16日 08:27
  • 8KB
  • 下载

数据结构实验一--单链表的基本操作的算法

1、 掌握单链表存储结构的类型定义; 2、 实现单链表各种基本运算的算法。 3、 实现单链表各种基本运算的算法以及改进实验代码。...

算法2-8~2-11:链表的基本操作

链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会在其中某些时候让你查找某...
  • Procher
  • Procher
  • 2015年03月30日 21:53
  • 371

新手学习数据结构与算法---单链表的基本操作

单链表操作。。。 大家指点一下。 //单链表及其基本操作 //这里的链表都是带头结点的------------- #include #include //用来进行动态...
  • zsjgs
  • zsjgs
  • 2011年10月16日 12:06
  • 405

Acm Club 1326:算法2-8~2-11:链表的基本操作

题目描述 链表是数据结构中一种最基本的数据结构,它是用链式存储结构实现的线性表。它较顺序表而言在插入和删除时不必移动其后的元素。现在给你一些整数,然后会频繁地插入和删除其中的某些元素,会...

HNCU1326:算法2-8~2-11:链表的基本操作

http://hncu.acmclub.com/index.php?app=problem_title&id=111&problem_id=1326 题目描述 链表是数据结构中一种最基本的数据结构,...

数据结构与算法-链表的基本操作---ShinPans

//链表操作:建立、插入、删除、查找、倒置、删除等基本操作 #include #include typedef  struct LNode {       int data;     ...

[数据结构与算法分析] 单链表基本操作的实现

这几天还在啃Weiss书的Ch.3,随手把书上单链表基本操作的代码打了一遍,顺便补充了一点自己写的东西(一堆注释以及几个函数),经过测试应该是没问题。   这次尝试用所谓的"Google Style"...

算法1:链表的基本操作

算法1:链表的基本操作编程实现链表的基本操作,包括插入,删除,查找,逆序,打印,获取长度等基本操作。用c++实现如下:定义LinkList头文件#include #include //链表数据结构体...
  • pplin
  • pplin
  • 2017年02月28日 18:07
  • 154
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:链表的操作和基本算法 java
举报原因:
原因补充:

(最多只允许输入30个字)