链表是一种常见的数据结构,无论是实际应用还是面试中,出现的频率都比较高,链表适宜存储关系不固定的数据,属于动态存储,区别于数组结构的静态存储。本篇小博主要围绕三个常见的链表问题进行分析。
一、建立一个自己的链表结构
class node {
<span style="white-space:pre"> </span>int data;
node next;
public node(int data) {
this.data = data;
}
}
二
、判断链表是否存在环
思路:设置两个指针,一快一慢(目前市场上貌似都是这种解法),如果快指针能和慢指针重合,则说明链表存在环。代码如下:
public static boolean IsLoop(node head) {
node p = head;
node q = head.next;
while(p != q && q != null) {
p = p.next;
q = q.next.next;
}
if(p == q) {
return true;
}
else {
return false;
}
}
三
、环的长度
思路:计算快慢指针第一次相遇与第二次相遇之间的循环次数,即为环的长度。
public static int LoopLength(node head) { //单链表快慢指针第一次到第二次相遇之间的步长即是
node p = head;//慢指针
node q = head.next;//快指针
int flag = 0;
int res = 0;
while(q != null) {
if(p == q) { //首次相遇 flag变为1
flag++;
}
if(flag == 1) {
res ++;
}
if(flag == 2) { //第二次相遇 break
break;
}
p = p.next;
q = q.next.next;
}
return res;
}
四
、寻找环的起点
思路:可以用hashtable
public static node LoopStart(node head) {
Hashtable<node,Integer> table = new Hashtable<node,Integer>();
while(head != null) {
if(table.containsKey(head)) {
break;
}
else {
table.put(head, 1);
}
head = head.next;
}
return head;
}
五、测试
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;n5.next = n2;
//1、检测有环没有
System.out.println(IsLoop(n1));
//2、查看环的长度
System.out.println(LoopLength(n1));
//3、环的起始点
System.out.println(LoopStart(n1).data);
}