shz.core.node.SNode Maven / Gradle / Ivy
package shz.core.node;
import java.io.Serializable;
import java.util.function.Consumer;
import java.util.function.Predicate;
/**
* 单向链表节点
*/
@SuppressWarnings("unchecked")
public interface SNode> extends Serializable {
T next();
default T next(int i) {
if (i < 0) return null;
if (i == 0) return (T) this;
T next = next();
return next == null ? null : next.next(--i);
}
void next(T node);
default T addNext(T node) {
node.next(next());
next(node);
return node;
}
T addPrev(T node);
void poll();
default T find(Predicate super T> predicate) {
if (predicate == null) return null;
for (T next = (T) this; next != null; next = next.next()) if (predicate.test(next)) return next;
return null;
}
default void forEach(Predicate super T> predicate) {
if (predicate == null) return;
for (T next = (T) this; next != null; next = next.next()) if (predicate.test(next)) break;
}
default void forEach(Consumer super T> consumer) {
if (consumer == null) return;
for (T next = (T) this; next != null; next = next.next()) consumer.accept(next);
}
default void reverse() {
T next = next();
if (next == null) return;
T cur = next.next();
next.next(null);
while (cur != null) {
next = cur.next();
cur.next(next());
next(cur);
cur = next;
}
}
default T last(int k) {
if (k <= 0) return (T) this;
T next = next();
if (next == null) return null;
T fast = next, slow = next;
int i;
for (i = 0; i < k && fast != null; ++i) fast = fast.next();
if (i < k) return null;
while (fast != null) {
slow = slow.next();
fast = fast.next();
}
return slow;
}
/**
* 交叉节点
*/
default T loopNode() {
T next = next();
if (next == null) return null;
//快慢指针,快指针以两倍的速度移动,若与慢指针相遇则存在环
T fast = next, slow = next;
//相遇节点
T meetNode = null;
while (fast != null && fast.next() != null) {
slow = slow.next();
fast = fast.next().next();
if (slow == fast) {
meetNode = fast;
break;
}
}
if (meetNode == null) return null;
//设 slow移动s 则fast移动2s
//设 环长=r 则 2s=s+nr,即 s=nr
//设 链表长度=L,起点到交叉点距离a,交叉点与相遇点距离x
//则 a+x = slow移动距离 = s = nr, r = L-a
//a+x = (n-1)r + r = (n-1)r + L-a
//a = (n-1)r + L-a-x
//即 起点到交叉点的距离 = 相遇点到交叉点的距离 + 环长的倍数
//则 起点指针与相遇点指针必定在交叉点相遇
fast = next;
while (fast != meetNode) {
fast = fast.next();
meetNode = meetNode.next();
}
return fast;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy