插入方法如何在链表中工作?

时间:2016-01-05 19:13:44

标签: java

我尝试使用三个类BIntSetNode来实现链接列表。

以下是我的解决方案书中的代码。我需要知道两件事:

  1. 在课程B中,我不知道在main方法中写什么来运行我的代码。
  2. 我需要有人在班级insert中向我描述B方法。我理解if方法中的第一个insert语句,但我不理解if中的其他insert method语句。
  3. 以下是三个类:

    package person;
    
    public class B implements IntSet {
        private Node first;
        private int size;
    
        public static void main(String[] args) {
        }
    
        public B() {
            first = new Node(Integer.MIN_VALUE, Integer.MIN_VALUE);
            first.next = new Node(Integer.MAX_VALUE, Integer.MAX_VALUE);
        }
    
        @Override
        public boolean contains(int nbr) {
            // TODO Auto-generated method stub
            Node p = first;
            while (p != null) {
                if (p.min <= nbr && p.max >= nbr) {
                    return true;
                }
                if (p.min > nbr) {
                    return false;
                }
                p = p.next;
            }
            return false;
        }
    
        @Override
        public boolean insert(int nbr) {
            // TODO Auto-generated method stub
            Node p = first;
            while (p != null) {
                if (p.min <= nbr && p.max >= nbr) {
                    return false;
                }
                if (p.max + 1 == nbr && p.next.min - 1 == nbr) {
                    p.max = p.next.max;
                    p.next = p.next.next;
                    break;
                } else if (p.max + 1 == nbr) {
                    p.max = nbr;
                    break;
                } else if (p.next.min - 1 == nbr) {
                    p.next.min = nbr;
                    break;
                } else if (p.max < nbr && p.next.min > nbr) {
                    Node n = new Node(nbr, nbr);
                    n.next = p.next;
                    p.next = n;
                    break;
                }
                p = p.next;
            }
            size++;
            return true;
        }
    
        @Override
        public int size() {
            // TODO Auto-generated method stub
            return size;
        }
    }
    
    package person;
    
    public interface IntSet {
        /** Tar reda på om nbr finns i mängden. */
        boolean contains(int nbr);
    
        /**
         * Sätter in nbr i mängden om det inte redan finns. Returnerar true om nbr
         * kan sättas in i mängden, i annat fall false.
         */
        boolean insert(int nbr);
    
        /* Tar reda på antal tal i mängden. */
        public int size();
    }
    
    package person;
    
    class Node {
        int min;
        int max;
        Node next;
    
        Node(int min, int max) {
            this.min = min;
            this.max = max;
            next = null;
        }
    }
    

    enter image description here

2 个答案:

答案 0 :(得分:1)

首先在toString课程中实施B方法。以下是toStringmain方法的代码。

public String toString() {
        StringBuilder builder = new StringBuilder();
         Node p = first;
         while (p != null) { 
             builder.append("[").append(p.min).append(",").append(p.max).append("]");
             p = p.next;
         }
         return builder.toString();
    }

main方法

public static void main(String[] args) {
    B b = new B();

    System.out.println("Before any insert :" +b);

    b.insert(1);
    b.insert(4);

    System.out.println("After first insert :" +b);

    b.insert(18);
    b.insert(23);

    System.out.println("After second insert :" +b);

    b.insert(25);
    b.insert(25);

    System.out.println("After third insert :" +b);

    b.insert(28);
    b.insert(57);

    System.out.println("After fourth insert :" +b);
}
  

输出

Before any insert :[-2147483648,-2147483648][2147483647,2147483647]
After first insert :[-2147483648,-2147483648][1,1][4,4][2147483647,2147483647]
After second insert :[-2147483648,-2147483648][1,1][4,4][18,18][23,23][2147483647,2147483647]
After third insert :[-2147483648,-2147483648][1,1][4,4][18,18][23,23][25,25][2147483647,2147483647]
After fourth insert :[-2147483648,-2147483648][1,1][4,4][18,18][23,23][25,25][28,28][57,57][2147483647,2147483647]

关于你的第二个问题 - 理解insert方法。如果给定数字的差异为1,则第二个和第三个if语句增加节点的最大值或减少下一个节点的最小值。

如果给定的数字不属于任何给定范围,则最后一次插入将以相同的最小值和最大值创建一个新节点。

我尽力解释,另一种方法是在调试模式下运行main程序,这会让你清楚地知道发生了什么。

答案 1 :(得分:0)

嗯,有点奇怪。以前没见过这样的东西,但是锻炼起来并不困难。这里要记住的一件事是,这是跟踪数字的范围。在底部的示例图片中,数据结构表示的数字范围是1-4,18-23,25-25和28-57。在此结构中添加数字时,您将创建一个新范围,组合两个范围,将范围的最小值或最大值扩展为1,或者发现该数字已在其中一个范围内表示。

1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if (p.min <= nbr && p.max >= nbr) {
    return false;
}

这意味着您给出该方法的数字在节点的最小值和最大值之间,并且该方法将返回false。凉。这是发现该数字已经在其中一个范围选项中表示。

2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

if (p.max + 1 == nbr && p.next.min - 1 == nbr) {
    p.max = p.next.max;
    p.next = p.next.next;
    break;
}

^在这种情况下,数字大于当前节点的最大值,并且小于下一个节点的最小值。想象一下两个节点:

Node 1:  min -> 4, max -> 8
Node 2:  min -> 10, max -> 13
Input Number: 9

因此,我们在这里得到的是节点1中表示的数字4 - 8和节点2中表示的10 - 13。当插入数字9时,我们现在有4-8,9-9,10-13代表。以这种方式存储它没有任何意义。表示4-13表示与表示4-8,9-9和10-13完全相同。那么,这样做是将下一个节点的最大值(在这种情况下为10)和最大值当前节点max,然后转储节点2.所以我们来自:

Node 1:  min -> 4, max -> 8, nextNode -> Node 2
Node 2:  min -> 10, max -> 13, nextNode -> Node 3

Node 1: min -> 4, max -> 13, nextNode -> Node 3

这是结合两个范围选项。

3 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

else if (p.max + 1 == nbr) {
    p.max = nbr;
    break;
}

因为该数字仅比当前节点max多一个,所以您只需将当前节点max替换为1。因此,对于范围为1-3的一个节点,您插入4并将1-3节点更改为1-4。

else if (p.next.min - 1 == nbr) {
    p.next.min = nbr;
    break;
}

与最后一个相同,期望你“扩大”分钟。因此,范围为4-7的节点,插入3,4,7变为3-7。以上两个都是扩展范围选项。

4 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

else if (p.max < nbr && p.next.min > nbr) {
    Node n = new Node(nbr, nbr);
    n.next = p.next;
    p.next = n;
    break;
}

在这种情况下,数字位于两个范围之间。范围1:4 - 8,范围2:17 - 24.在这种情况下输入14并且您无法将其装入这些范围中的任何一个或扩展范围以适合它。因此,您创建一个新的Range并将它放在它们之间。它变为,范围1:4-8,范围2:14-14,范围3:17-24。这是创建新范围选项。

5 ~~~~~~~~~~~~~~~~~

p = p.next;

如果您已经到达此处,则上述方案均未应用。此时,您将转到下一个节点,并检查上述任何条件是否适用于此。

我希望这有帮助,我花了一些时间来解决这个问题,但我很确定上面的一切都是正确的。