您的位置:首页 > 理论基础 > 数据结构算法

数据结构之链表面试题汇总(三)判断单链表是否有环、取出环的起始点、得到有环链表中环的长度

2017-11-02 21:17 603 查看
title: 数据结构之链表面试题汇总(三)判断单链表是否有环、取出环的起始点、得到有环链表中环的长度

date: 2016-08-18 9:14:00

categories: 数据结构

版权声明:本站采用开放的[知识共享署名-非商业性使用-相同方式共享 许可协议]进行许可

所有文章出现的代码,将会出现在我的github中,名字可以根据类全名来找,我在github中的文件夹也会加目录备注。

判断单链表是否有环

思路:

首先判断链表是否为空,为空抛异常

利用”双指针“方法:

一个指针每次移动一个节点,另外一个指针每次移动两个节点,如果第一个指针所对应的节点等于第二个指针所对应的节点,那么这个链表有环

在这里需要注意传入来链表的节点数

图解:









代码实现:

public static boolean hasLoopReturnBoolean(Node head) {
Node first = head;
Node second = head;
// if the head is null return exception
if (head == null || head.getNext() == null)
return false;
// move first on step backward and the second move twice at once
// if the condition of the judgement without the second.getNext()!=null
// when it reach the tail it will raise the NPE
while (second != null && second.getNext() != null) {
first = first.getNext();
second = second.getNext().getNext();
// if first=second return true
if (first == second)
return true;
}
// else false
return false;
}


测试代码:有环

public class ReverseLinkedListTest {

public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
node5.setNext(node3);

System.out.println(HasLoop.hasLoopReturnBoolean(node1));
}

}


运行结果:



测试代码:无环:即把第五个节点的设置下一个节点的代码注释掉

public class ReverseLinkedListTest {

/**
* @param args
*/
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
// node5.setNext(node3);

System.out.println(HasLoop.hasLoopReturnBoolean(node1));
}

}


运行结果:



有环单链表中,得到环的起始点

思路:

可以借助上一题中判断是否有环的方法,在循环中判断first=second的时候,如果相等,直接返回first或者second即可。

代码实现:

public static Node hasLoopReturnNode(Node head) {
Node first = head;
Node second = head;
// if the head is null return exception
if (head == null || head.getNext() == null)
return null;
// move first on step backward and the second move twice at once
// if the condition of the judgement without the second.getNext()!=null
// when it reach the tail it will raise the NPE
while (second != null && second.getNext() != null) {
first = first.getNext();
second = second.getNext().getNext();
// if first=second return true
if (first == second)
return first;
}
// else without loop
return null;
}


测试代码:有环

public class ReverseLinkedListTest {

/**
* @param args
*/
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
node5.setNext(node3);

System.out.println(HasLoop.hasLoopReturnNode(node1).getRecord());
}

}


运行结果:



无环测试代码:

public class ReverseLinkedListTest {

/**
* @param args
*/
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
// node5.setNext(node3);

System.out.println(HasLoop.hasLoopReturnNode(node1).getRecord());
}

}


运行结果:



如果没有环,返回的是null,如果要读取里面的数据,就会抛空指针异常

得到有环链表中环的长度

思路:

继续继承判断链表是否有环的方法,只不过在判断的时候,把一个链表的头节点传到函数中

首先获取该链表的环开始的节点

再定义两个变量来记录返回节点信息,即环开始的节点

一个留作备用,另外一个用来比较

再定义一个变量来记录环的长度

循环是死循环,因为有环链表永远到不了头

通过判断现在的节点是否等于环开始节点来跳出循环,并且返回环长度

代码实现:

public static int getCycleLength(Node head) {
// define the variable to record the length
int length = 0;
// judge the list has the loop or not
Node loop = hasLoopReturnNode(head);
// juege the head is null,
if (loop == null)
// true return 0
return length;
// while the head=current the return the length
Node flat = loop;
Node current = loop;
while (current != null) {
current = current.getNext();
length++;
if (current == flat) {
return length;
}
}
return length;
}


测试代码:有环

public class ReverseLinkedListTest {

/**
* @param args
*/
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
node5.setNext(node3);

System.out.println(HasLoop.getCycleLength(node1));
}

}


运行结果:



测试代码:无环:

public class ReverseLinkedListTest {

/**
* @param args
*/
public static void main(String[] args) {
Node node1 = new Node(1);
Node node2 = new Node(2);
Node node3 = new Node(3);
Node node4 = new Node(4);
Node node5 = new Node(5);
node1.setNext(node2);
node2.setNext(node3);
node3.setNext(node4);
node4.setNext(node5);
// node5.setNext(node3);

System.out.println(HasLoop.getCycleLength(node1));
}

}


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐