?? How do I detect if a linked list has a ring? This is a high frequency of the face of the question.
?? The following is a list of links that contain loops.
(Image from http://www.nowamagic.net/librarys/veda/detail/2245
A lot of articles about the data structure of the site, there are other information, you can see)
I have three ways to solve problems here:
- Fast and Slow pointer method: Two different speed of the pointer traversal will always meet;
- The relationship between the vertex number of the ring and the edge equality;
- Two pointers traverse to determine if the steps are equal.
?? In order to check whether the linked list contains loops, we need to construct a linked list with a ring first.
?? So I added two methods on the basis of the previous source code as follows:
/** * @TODO 设置成循环链表 */public void setLoop(){ FOLinkedNode<E> p = new FOLinkedNode<E>(); p=this.header; FOLinkedNode<E> q = new FOLinkedNode<E>(); q = this.last(p); q.addNext(p);}/** * @TODO 指定某个位置来设置链表还有环 * @param index 链表的某个位置 */public void setIndexLoop(int index){ validateIndex(index); FOLinkedNode<E> p = new FOLinkedNode<E>(); p=get(index); FOLinkedNode<E> q = new FOLinkedNode<E>(); q=last(this.header); q.addNext(p);}
1. Fast and Slow pointer method:
The code is as follows:
/** * @TODO 判断链表是否含有环(快慢指针法) * @return true or false */public boolean hasLoop(){ FOLinkedNode<E> p = new FOLinkedNode<E>(); FOLinkedNode<E> q = new FOLinkedNode<E>(); p=this.header; if(p!=null){ q = p.next; while(p!=null && q!=null && q.next!=null){ if(p==q || p==q.next){ return true; } q =q.next.next; p = p.next; } } return false;}
2. The number of vertices of the ring and the relationship of equal edges.
?? This is a method that I think of, because it is a linked list, so I initially assumed that the single-linked list, and my single-linked list is set to length, so that when the decision is to include the ring can be used in length.
?? Whether the pointer is empty and the length of each traversal minus 1 operation to make a while loop, so that if the length is equal to 0 when the pointer is not empty, then it is indicated that this list contains a ring. This takes advantage of the relationship between the number of vertices of the ring and the edge equality.
The code is as follows:
/** * @TODO 利用环的顶点数和边数相等的关系进行判断是否含有环 * @return true or false */public boolean hasLoop2(){ FOLinkedNode<E> temp = new FOLinkedNode<E>(); temp = this.header.next; int tempSize = this.size(); while (temp != null) { tempSize--; if(tempSize<=0){ return true; } temp = temp.next; } return false;}
?? This method I actually think of when I print the list. If it is a single-linked list, then you can print it as long as the pointer is null, and if it is a circular linked list or a linked list containing the ring, if you want to print into a dead loop, and then think of the length of the linked list to print the linked list. So when it is necessary to determine whether the linked list contains a ring, there is a need to add another condition, that is, if the pointer is empty, then the problem is solved.
By the way, paste the code for the improved ToString method:
@Overridepublic String toString() { return "[" + this.NodesToString(this) + "]";}/** * @param foLinkedList * @TODO 设置单链表的长度 * @return 单链表的节点字符串序列 */private String NodesToString(FOLinkedList<E> foll) { StringBuffer sb = new StringBuffer(); if (foll.header != null) { sb.append(foll.header.getE()); FOLinkedNode<E> temp = new FOLinkedNode<E>(); temp = foll.header.next; int tempSize = foll.size() - 1; while (temp != null && tempSize!=0) { sb.append(", " + temp.getE()); temp = temp.next; tempSize--; } } return sb.toString();}
3. Two pointer traversal to determine if the steps are equal
Ideas:
?? Set two working hands P, Q,p always go forward, but Q every time to start from the beginning, for each node, see p Walk the number of steps is the same as Q. For example, p went from a to D, took 4 steps, and Q took 14 steps. Thus the number of steps varies, there are contradictions, the existence of the ring.
?? This method is slightly more than the previous two methods, there is no code to write.
?? Finally put the test code, the code of the comment is used before the test code, can be ignored, you can try it yourself.
public static void Main (string[] args) {//folinkedlist<string> fol = new folinkedlist<string> ();// for (int i = 1; I <= 8; i++) {//Fol.add ("element" +i);//}//Fol.add ("element" +2);//Fol.add ("element" +7); Fol.add ("element" +2);//Fol.add ("element" +2);//Fol.add ("element" +3);//Fol.add ("element" +11);//Fol.add ("element" + 1); /Fol.add ("element" +9);//SYSTEM.OUT.PRINTLN (FOL);//fol = folinkedlist.removerepeatelement (fol);//System. OUT.PRINTLN (fol);//System.out.println (Fol.size ());//Fol.insert (9, "xxx");//SYSTEM.OUT.PRINTLN (FOL);// System.out.println (Fol.size ());//Fol.set (9, "element 9");//SYSTEM.OUT.PRINTLN (FOL);//folinkednode<string& Gt E = Fol.remove (6);//System.out.println (e);//SYSTEM.OUT.PRINTLN (FOL);//System.out.println (Fol.size ());// folinkedlist<string> newfol = new folinkedlist<string> ();//for (int i = 1; I <= fol.size (); i++) {//Newfol. AddFirst (Fol.get (i). Gete ());//}//System.out.println (newfol);//folinkedlist<integer> a = new Folin Kedlist<integer> ();//folinkedlist<integer> B = new folinkedlist<integer> ();//for (int i = 0, J=1; I < 10; I++,J=J+2) {//A.add (j);//}//for (int i = 0,j=0; I < i++,j=j+3) {//B.add (j);// }//System.out.println (a);//System.out.println (b);//folinkedlist<integer> C = a.merge (b);//Sy Stem.out.println (c); Test if the chain list contains a ring folinkedlist<integer> x = new folinkedlist<integer> (); for (int i = 1; i <=; i++) {x.add (i); } System.out.println (x); System.out.println (X.size ()); System.out.println ("HASLOOP2:" +x.hasloop2 ()); System.out.println ("Hasloop:" +x.hasloop ()); X.setindexloop (10); SYSTEM.OUT.PRINTLN (x); System.out.println (X.size ()); System.out.println ("HASLOOP2:" +x.hasloOP2 ()); System.out.println ("Hasloop:" +x.hasloop ()); }
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Java data structure-list of linear tables application-detect if a linked list has a ring