Java 链表的问题

Java 链表的问题,java,Java,我对RationalSet类的主要方法有问题,它是rationalsnode的链接列表。在这个方法中,我创建了两个列表和两个节点,第一个列表有两个节点,但是第二个列表只有一个,但是当我这样做时,第二个列表有两个节点。我不知道为什么 这是我的密码: 理性集 class RationalSet { static Scanner keyboard = new Scanner(System.in).useLocale(Locale.US); RationalNode first, pr

我对
RationalSet
类的主要方法有问题,它是
rationalsnode
的链接列表。在这个方法中,我创建了两个列表和两个节点,第一个列表有两个节点,但是第二个列表只有一个,但是当我这样做时,第二个列表有两个节点。我不知道为什么

这是我的密码:

理性集

class RationalSet {
    static Scanner keyboard = new Scanner(System.in).useLocale(Locale.US);

    RationalNode first, previousIP, IP, previousAux;
    int size;

    public RationalSet() {
        first = null;
        previousIP = null;
        IP = null;
        size = 0;
    }

    public int cardinal() {
        return size;
    }

    private boolean isEmpty() {
        return first == null;
    }

    public boolean belongs(RationalNode r) {
        return position(r) != null;
    }

    public void insert(RationalNode r) {
        if (isEmpty()) {
            first = r;
            previousIP = first;
            IP = previousIP.next;
            size++;
        } else if (!belongs(r)) {
            previousIP.next = r;
            previousIP = previousIP.next;
            IP = previousIP.next;
            size++;
        }
    }

    public void delete(RationalNode r) {
        if (!isEmpty()) {
            RationalNode aux = position(r);
            if (aux != null) {
                if (aux == first)
                    first = aux.next; // I'm comparing references
                else
                    previousAux.next = aux.next;
                size--;
            }
        }
    }

    private RationalNode position(RationalNode r) {
        RationalNode aux = first;
        while (aux != null && !aux.equals(r)) {
            previousAux = aux;
            aux = aux.next;
        }
        return (aux == null) ? null : aux;
    }

    public boolean exists(RationalSet c) {
        RationalNode aux = c.first;
        while (aux != IP && belongs(aux))
            aux = aux.next;
        return aux == null;
    }

    public boolean equals(RationalSet c) {
        if (c.cardinal() != cardinal())
            return false;
        if (this == c || (isEmpty() && c.isEmpty()))
            return true;
        return exists(c) && c.exists(this);
    }

    public String toString() {
        String s = "{";
        for (RationalNode aux = first; aux != null; aux = aux.next)
            s += aux.toString() + ", ";
        return s + "}";
    }

    public Object clone() {
        RationalSet c = new RationalSet();
        for (RationalNode aux = first; aux != null; aux = aux.next)
            c.insert((RationalNode) aux.clone());
        return (Object) c;
    }

    public RationalSet union(RationalSet c) {
        RationalSet u = (RationalSet) this.clone();
        for (RationalNode aux = c.first; aux != null; aux = aux.next)
            u.insert(aux);
        return u;
    }

    public RationalSet intersection(RationalSet c) {
        RationalSet in = new RationalSet();
        for (RationalNode aux = first; aux != null; aux = aux.next)
            if (c.belongs(aux))
                in.insert(aux);
        return in;
    }

    public static void main(String[] args) {
        RationalSet c1 = new RationalSet(), 
                    c2 = new RationalSet();
        Rational r1 = new Rational(-2, 3),
                 r2 = new Rational(1, 1);
        RationalNode n1 = new RationalNode(r1), 
                     n2 = new RationalNode(r2);
        c1.insert(n1);
        c1.insert(n2);

        c2.insert(n1);

        RationalSet u = c1.union(c2);

        System.out.println(u);
        System.out.println(c1.intersection(c2));
    }
}
理性节点

class RationalNode {
    Rational rational;
    RationalNode next;

    public RationalNode(Rational r) {
        rational = r;
        next = null;
    }

    public RationalNode(Rational r, RationalNode s) {
        rational = r;
        next = s;
    }

    public boolean equals(Object obj) {
        if (obj instanceof RationalNode) {
            RationalNode a = (RationalNode) obj;
            if (this == a)
                return true;
            return (rational == null) ? false : rational.equals(a.rational);
        } else
            return false;
    }

    public String toString() {
        return rational.toString();
    }

    public Object clone() {
        return (Object) new RationalNode((Rational) rational.clone());
    }
}
理性的

class Rational {
    static Scanner keyboard = new Scanner(System.in).useLocale(Locale.US);

    private long num, den;

    public Rational(long n, long d) {
        num = n;
        den = d;
        simplify();
    }

    Rational(Scanner t) {
        System.out.print("Give me a numerator: ");
        num = t.nextInt();
        System.out.print("Give me a denominator: ");
        den = t.nextInt();
        simplify();
    }

    public static Rational read(Scanner input) {
        System.out.print("Numerator: ");
        long n = input.nextLong();
        System.out.print("Denominator: ");
        long d = input.nextLong();
        return new Rational(n, d);
    }

    public long num() {
        return num;
    }

    public long den() {
        return den;
    }

    public Rational inverse() {
        return new Rational(den, num);
    }

    public static Rational inverse(Rational r) {
        return new Rational(r.den(), r.num);
    }

    public void autoInverse() {
        long aux = num;
        num = den;
        den = aux;
    }

    public Rational opposite() {
        return new Rational(-num, den);
    }

    public Rational multiply(Rational r) {
        return new Rational(r.num * num, den * r.den);
    }

    public Rational divide(Rational r) {
        return multiply(r.inverse());
    }

    public Rational sum(Rational r) {
        return new Rational(num * r.den + den * r.num, den * r.den);
    }

    public Rational deduct(Rational r) {
        return sum(r.opposite());
    }

    public void simplify() {
        if (num == 0 && den != 0)
            den = 1;
        else if (num != 0 && den == 0)
            num = (num >= 0) ? 1 : -1;
        else if (num != 0 && den != 0) {
            long numAbs = Math.abs(num), denAbs = Math.abs(den);
            long lcd = lcd(numAbs, denAbs);
            long signDen = den / denAbs;
            num = signDen * (num / lcd);
            den = signDen * (den / lcd);
        }
    }

    private static long lcd(long a, long b) {
        if (a == b)
            return a;
        else if (a > b)
            return lcd(a - b, b);
        else
            return lcd(a, b - a);
    }

    public String toString() {
        return num + "/" + den;
    }

    public boolean equals(Rational r) {
        return r.num == num && r.den == den;
    }

    public Object clone() {
        return (Object) new Rational(num, den);
    }

    public static void main(String a[]) {
        Rational r1 = new Rational(23, -38), r2 = new Rational(4, 2);
        System.out.println(r1.toString() + " " + r1.num + " / " + r1.den);
        r1 = r1.inverse();
        System.out.println(r1 + " " + r1.num + " / " + r1.den);
        r1 = inverse(r1);
        System.out.println(r1 + " " + r1.num + " / " + r1.den);
        r1.autoInverse();
        System.out.println(r1 + " " + r1.num + " / " + r1.den);
        r1 = new Rational(23, -38);
        Rational r3 = new Rational(23, -38);
        System.out.println((r1 == r3) + "  " + r1.equals(r3));
    }
}

不应在集合外部创建节点。当你这样做的时候

c1.insert(n1);
首先执行此代码

if (isEmpty()) {
    first = r;
    previousIP = first;
    IP = previousIP.next;
    size++;
}
它保存在
第一个
以前的IP
当前节点中,该节点也是由
n1
存储的。但是当你以后执行的时候

c1.insert(n2);
由于
c1
不再为空,因此执行
else
部分

} else if (!belongs(r)) {
    previousIP.next = r;
    previousIP = previousIP.next;
    IP = previousIP.next;
    size++;
}
它将
previousIP.next
设置为
r
,并且由于
previous
与参考
n1
r
持有相同的对象,因此
n2
有效地设置了
n1.next=n2

最后,您要将
n1
添加到第二组
n2

c2.insert(n1);
但这意味着您正在添加
n1
,它已经在内部指向
n2
。这就是为什么
c1
c2
似乎包含相同的结构

您应该做的是重写
insert
方法,以便在内部创建自己的独立
RationalNodes
。因此,您的代码不应该专注于接受
理性节点
,而是
理性

public void insert(Rational r) {
    if (isEmpty()) {
        first = new RationalNode(r);//changed
        previousIP = first;
        IP = previousIP.next;
        size++;
    } else if (!belongs(r)) {
        previousIP.next = new RationalNode(r);//changed
        previousIP = previousIP.next;
        IP = previousIP.next;
        size++;
    }
}
您还需要重新设计处理
RationalNode
的其余代码,以处理
Rational


顺便说一句,您可以在
RationalSet
中创建您的
RationalNode
私有内部类。这样可以更明确地说,这个类的实例应该只由
RationalSet
创建,并且必须属于它的一个实例。

如果代码很容易翻译,那么请这样做。这里并不是每个人都说西班牙人为什么要编写自己的链表类,人们可以简单地扩展已经定义的链表类的功能…@CommuSoft这很可能是家庭作业,在学习基本算法和数据结构时非常常见。是的,我正处于职业生涯的第一年。@MarcoCanora
RationalNode
的代码在哪里?