题目一:在有环的链表中,怎么找到环的起始位置
代码思路:首先还是快慢指针,当快指针追上慢指针的时候,说明链表里有环。
假设:环内有y个元素,环外有x个元素,快慢指针在第s个相遇,相遇的时候快指针已经绕环n圈
那么慢指针总共走了x+s元素;如果按照慢指针走一步,快指针走两步,那么快指针总共走了2(x+s)
但是如果直接看快指针走了多少步:x+n×y+s;
得到等式:x+n×y+s=2(x+s)——> x+s=n×y——>x=y×(n-1)+y-s
根据x=y×(n-1)+y-s这个等式可以看出,当快慢指针相遇后,从相遇地点到环的起始位置所经过的元素,跟从起始位置到起始位置所经过的元素相等。
public class FindCiecle {
public static void main(String[] args) {
Node one = new Node(null, "one");
Node two = new Node(null, "two");
Node three = new Node(null, "three");
Node four = new Node(null, "four");
Node five = new Node(null, "five");
Node six = new Node(null, "six");
one.next = two;
two.next = three;
three.next = four;
four.next = five;
five.next = six;
six.next = three;
System.out.println(findCiecleNode(two).value);
}
public static Node findCiecleNode(Node begin) {
Node quick = begin;
Node slow = begin;
//先判断链表是否有环,并且得到快慢指针相遇位置
while (quick.next != null && quick.next.next != null) {
quick = quick.next.next;
slow = slow.next;
if (quick == slow) {
break;
}
}
//这是链表没有环的情况
if (quick.next == null || quick.next.next == null) {
return null;
}
//这是有环后,寻找环的起始位置
if (quick==slow){
quick=begin;
while (quick!=slow){
quick=quick.next;
slow=slow.next;
}
return slow;
}
return slow;
}
}
class Node {
String value;
Node next;
public Node(Node next, String value) {
this.value = value;
this.next = next;
}
public Node() {
}
}
题目二反序链表
代码思路:创建一个头结点,然后利用头插法,逐步遍历原链表,在遍历的过程中,把结点都插入到头结点之后
import javax.sound.midi.Soundbank;
public class ReLinked {
public static void main(String[] args) {
Node one = new Node(null, "one");
Node two = new Node(null, "two");
Node three = new Node(null, "three");
Node four = new Node(null, "four");
Node five = new Node(null, "five");
Node six = new Node(null, "six");
one.next = two;
two.next = three;
three.next = four;
four.next = five;
five.next = six;
six.next = null;
reLinkedNode(one);
System.out.println(one);
}
public static Node reLinkedNode(Node head) {
Node mark = head;
Node begin = null;
Node temp ;
while (mark != null) {
temp=mark;
mark=mark.next;
temp.next=begin;
begin=temp;
}
return begin;
}
}
class Node {
String value;
Node next;
public Node(Node next, String value) {
this.value = value;
this.next = next;
}
public Node() {
}
}
利用链表实现一个线性表
1.对链表的删除:a.对头结点的删除要单独处理
b.要对要删除的结点值为Null特殊处理,在判断的时候要注意使用==还是用equals
2.对于查找功能一般是contains,返回值为boolean类型
在Java中,查找功能用的最多,所以在选择双向链表还是单向链表的时候,要从查找功能的效率下手
通常在工作的过程中,当代码出现了问题一般是先采用,在不同的地方输出,如果通过输出也不能看出哪里出了问题,再用Debug模式
public class Instrument {
private Node head;
private int size;
public boolean isEmpty() {
return size == 0;
}
public void add(String addNodeValue) {
if (addNodeValue == null) throw new IllegalArgumentException("parame is null");
Node node = new Node(null, addNodeValue);
Node end = head;
if (isEmpty()) {
head = node;
size++;
} else {
while (end.next != null) {
end = end.next;
}
end.next = node;
size++;
}
}
public boolean delete(String deleteNodeValue) {
if (deleteNodeValue == null) throw new IllegalArgumentException("parame is null");
if (isEmpty()) {
return false;
}
Node mark = head;
Node markpre=head;
if (deleteNodeValue.equals(mark.value) && size == 1) {
head = null;
size--;
return true;
}
while (mark.next != null) {
if (deleteNodeValue.equals(mark.value)&&head==mark){
head=head.next;
mark=null;
size--;
return true;
}
if (deleteNodeValue.equals(mark.value)){
markpre.next=mark.next;
mark.next=null;
size--;
return true;
}
markpre=mark;
mark=mark.next;
}
return false;
}
}
class Node {
String value;
Node next;
public Node(Node next, String value) {
this.value = value;
this.next = next;
}
public Node() {
}
}