All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.core.node.SNode Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
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 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 predicate) {
        if (predicate == null) return;
        for (T next = (T) this; next != null; next = next.next()) if (predicate.test(next)) break;
    }

    default void forEach(Consumer 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