为什么这个 while 循环陷入无限循环?

发布于 2024-09-28 01:39:10 字数 3257 浏览 7 评论 0原文

我正在研究一种混合数据结构,它是一个有序的双链表,其中每个节点都包含一个 SIZE 的数组[]。我的困难是add方法。

使用教授提供的单元测试,测试字符串被分解为单个字符,并使用提供的比较器添加到列表中。默认测试是 abcdefghijklmnopqrstuvwxyzaeiou

我编写的 add 方法很好地添加了第一项,但它不会超出该字符。由于该测试适用于班上的其他学生,因此一定是我的代码搞砸了。

我想出的代码是

boolean add(E item){
    Chunk<E> currentNode= head; //set lookup node to the head

    if (size==0) {
        //new chunk, connect it with head
        Chunk<E> newNode= new Chunk<E>(); 
        newNode.next= head;
        newNode.prev=head;
        head.next= newNode;
        head.prev= newNode;

        //add item and update counters
        ll.insertItem(newNode, item);
        size++;

        //System.out.println(currentNode.items[0]);
    }

    else {
        if (currentNode.next== head) {
            ll.insertItem(currentNode, item);
        }

        while (currentNode.next != head) {
            currentNode= currentNode.next;
            System.out.println(currentNode.items[0]);

            //if the add item is less than first item, move to previous node
            if (comp.compare(item, currentNode.items[0])<0) 
                currentNode= currentNode.prev;

            //if item fits within a chunk
            if (comp.compare(item, currentNode.items[0])> 0 && 
                    comp.compare(item, currentNode.items[currentNode.numUsed-1])<0) {
                ll.insertItem(currentNode, item);


                //otherwise, move search onto next node
            } else {
                currentNode= currentNode.next;
            }
        } 
    }
    return true;
}

ll.insertItem 是嵌套类中的一个辅助方法,它确定在数组中的哪个位置插入项目,如果数组已满,则将节点拆分为两个节点,复制后半部分旧节点到新节点,然后将项目添加到适当的节点。我将其实现为

public void insertItem(Chunk<E> node, E item) {
        if(node.numUsed==0) {
            node.items[0]=item;
            node.numUsed++;

        }else if (node.numUsed<chunkSize) {
            for (int i=0; i<=node.numUsed; i++) {
                if (comp.compare(item, node.items[i])>0) {
                    for (int j= node.numUsed; j>i; j--) {
                        node.items[j+1]= node.items[j];
                    }

                    node.items[i]= item;
                    node.numUsed++;
                }
            }
        } else {

            //make new chunk, determine which chunk item should be added
            Chunk<E> newChunk= newChunk(node);
            size++;

            //if item fits in new node
            if (comp.compare(item, newChunk.items[0])>0) {
                insertItem(newChunk, item);
            } else {
                insertItem(node, item); //item fits in old node
            }
        }
    }

我没有得到的就是为什么它陷入无限循环,特别是在测试字符串的第一个字符上。既然执行了 if (size==0) 条件,为什么代码会重复添加 a 字符?

附录 - RD 请求

System.out.println("insertion order: "+order);
    Comparator<String> comp = new StringCmp();
    ((CmpCnt)comp).resetCmpCnt();            // reset the counter inside the comparator
    ChunkList<String> clist = new ChunkList<String>(comp);
    for (int i = 0; i < order.length(); i++){
        String s = order.substring(i, i+1);
        clist.add(s);
    }

I'm working on a hybrid data structure that is an ordered double-linked list where each node contains an array[] of SIZE. My difficulty is the add method.

Using unit testing provided by the professor, a test string is broken up into individual characters and added to the list using a provided comparator. The default test is abcdefghijklmnopqrstuvwxyzaeiou

The add method I wrote adds the first item fine, but it doesn't advance past that character. Since the test works for other students in the class, it must be my code screwing things up.

The code I came up with is

boolean add(E item){
    Chunk<E> currentNode= head; //set lookup node to the head

    if (size==0) {
        //new chunk, connect it with head
        Chunk<E> newNode= new Chunk<E>(); 
        newNode.next= head;
        newNode.prev=head;
        head.next= newNode;
        head.prev= newNode;

        //add item and update counters
        ll.insertItem(newNode, item);
        size++;

        //System.out.println(currentNode.items[0]);
    }

    else {
        if (currentNode.next== head) {
            ll.insertItem(currentNode, item);
        }

        while (currentNode.next != head) {
            currentNode= currentNode.next;
            System.out.println(currentNode.items[0]);

            //if the add item is less than first item, move to previous node
            if (comp.compare(item, currentNode.items[0])<0) 
                currentNode= currentNode.prev;

            //if item fits within a chunk
            if (comp.compare(item, currentNode.items[0])> 0 && 
                    comp.compare(item, currentNode.items[currentNode.numUsed-1])<0) {
                ll.insertItem(currentNode, item);


                //otherwise, move search onto next node
            } else {
                currentNode= currentNode.next;
            }
        } 
    }
    return true;
}

ll.insertItem is a helper method in a nested class that determines which location in the array to insert the item, and if the array is full, splits the node into two nodes, copying the latter half of the old node to the new, then adds the item to the appropriate node.I implemented it as

public void insertItem(Chunk<E> node, E item) {
        if(node.numUsed==0) {
            node.items[0]=item;
            node.numUsed++;

        }else if (node.numUsed<chunkSize) {
            for (int i=0; i<=node.numUsed; i++) {
                if (comp.compare(item, node.items[i])>0) {
                    for (int j= node.numUsed; j>i; j--) {
                        node.items[j+1]= node.items[j];
                    }

                    node.items[i]= item;
                    node.numUsed++;
                }
            }
        } else {

            //make new chunk, determine which chunk item should be added
            Chunk<E> newChunk= newChunk(node);
            size++;

            //if item fits in new node
            if (comp.compare(item, newChunk.items[0])>0) {
                insertItem(newChunk, item);
            } else {
                insertItem(node, item); //item fits in old node
            }
        }
    }

WHat I'm not getting is why this is stuck in an infinite loop, especially on the first character of the test string. Since the if (size==0) conditional executes, why is the code repeating adding the a character?

Addenum- Requested by RD

System.out.println("insertion order: "+order);
    Comparator<String> comp = new StringCmp();
    ((CmpCnt)comp).resetCmpCnt();            // reset the counter inside the comparator
    ChunkList<String> clist = new ChunkList<String>(comp);
    for (int i = 0; i < order.length(); i++){
        String s = order.substring(i, i+1);
        clist.add(s);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

深白境迁sunset 2024-10-05 01:39:10

添加第一项后,您不会增加 numUsed

this:

if(node.numUsed==0) {
            node.items[0]=item;

        }

应该是:

if(node.numUsed==0) {
            node.items[0]=item;
            node.numUsed++;
        }

You are not incrementing numUsed after adding the first item

this:

if(node.numUsed==0) {
            node.items[0]=item;

        }

should be:

if(node.numUsed==0) {
            node.items[0]=item;
            node.numUsed++;
        }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文