Java 拆分数组-我的实现正确吗?

Java 拆分数组-我的实现正确吗?,java,data-structures,split,Java,Data Structures,Split,我正在为学校的混合数据结构编写代码,并正在调试代码。基本上,此结构是一个双链接列表和一个数组的组合,其中每个列表节点包含一个集合大小的数组。由于这是一种有序结构,因此必须作出规定,以识别完整阵列并将其平均分割为两个节点 这是我的代码,用于将节点一分为二,然后将父节点的数组值的后半部分复制到子节点 public Chunk<E> split(Chunk<E> node) { Chunk<E> newChunk= new Chunk<E>();

我正在为学校的混合数据结构编写代码,并正在调试代码。基本上,此结构是一个双链接列表和一个数组的组合,其中每个列表节点包含一个集合大小的数组。由于这是一种有序结构,因此必须作出规定,以识别完整阵列并将其平均分割为两个节点

这是我的代码,用于将节点一分为二,然后将父节点的数组值的后半部分复制到子节点

public Chunk<E> split(Chunk<E> node) {
  Chunk<E> newChunk= new Chunk<E>();
  newChunk.index= node.index++;

  //connect to previous node
  node.next= newChunk.next;
  newChunk.prev= node.prev;

  //connect to next node
  newChunk.next= node.next.next;
  node.next.prev= newChunk.prev;

  //adds the latter half of the array contents to the new node
  //and erases the same contents from the old node
  for (int i=chunkSize/2; i<node.numUsed; i++) {
   newChunk.items[i-chunkSize/2]= node.items[i];
   node.items[i]=null;
  }

  //update capacity counter for both chunks
  node.numUsed=chunkSize/2;
  newChunk.numUsed= chunkSize/2;

  return newChunk;

}
公共区块分割(区块节点){
Chunk newChunk=新Chunk();
newChunk.index=node.index++;
//连接到上一个节点
node.next=newChunk.next;
newChunk.prev=node.prev;
//连接到下一个节点
newChunk.next=node.next.next;
node.next.prev=newChunk.prev;
//将数组内容的后半部分添加到新节点
//并从旧节点中删除相同的内容

对于(inti=chunkSize/2;i来说,一个更好的问题是:“如何通过调试在源代码中隔离(跟踪)bug的位置?”

首先,您需要有一种方法来重现问题。看起来您已经有了。在一个非平凡的代码库中,您将需要对问题进行二进制搜索。在程序执行中有两个点a和B,其中程序在a中处于有效状态,但在B中不处于有效状态,请在a和B之间选择一个点C,并检查是否一切正常在C处正确。如果是,错误在C和B之间,或者在A和C之间。重复出现,直到你把它缩小到代码中非常小的一部分,这通常是非常明显的


这就留下了如何验证执行是否正确的问题。有多种方法可以做到这一点,但在调试器中执行程序、使用断点挂起执行并检查变量是否包含预期值可能是最有益的。要彻底回答这个问题,您应该编写一些单元测试。例如:

package so3898131;

import static org.junit.Assert.*;

import org.junit.Test;

public class ChunkTest {

  /** Ensure that the simplest possible case works as expected. */
  @Test
  public void testEmptySplit() {
    Chunk<Object> old = new Chunk<Object>();
    Chunk<Object> split = old.split(old);
    assertEquals(0, split.chunkSize);
    assertEquals(0, split.items.length);
    assertEquals(0, split.index);
    assertEquals(1, old.index);
  }

  @Test
  public void testSplitWithOneItem() {
    // TODO: make sure that after splitting one of the chunks contains
    // one element, the other none.
  }

  @Test
  public void testSplitWithTwoItems() {
    // TODO: make sure that after splitting a chunk with two elements
    // each of the new chunks contains exactly one of the elements.
    // Use assertSame(..., ...) to check it.
  }
}
然后我修改了代码,使测试成功运行。我必须用以下代码替换一些行:

// connect to previous and next node
Chunk<E> one = node, two = newChunk, three = node.next;
one.next = two;
two.prev = one;
two.next = three;
if (three != null)
  three.prev = two;
//连接到上一个和下一个节点
Chunk one=node,two=newChunk,three=node.next;
下一个=两个;
2.prev=1;
2.next=3;
如果(三!=null)
3.prev=2;

这就是我怀疑我的代码存在问题的一个原因,即新旧节点之间的“下一个”和“上一个”字段的链接。据我所知,我遵循了教科书中的规则和其他在线示例。因为你给了我最多的帮助,我将你的回答作为选择答案进行了检查。一位朋友帮助我理解了d通过使用一个人作为节点并将其手臂作为prev和next来链接节点。我的代码已被修改。从我在Eclipse调试器中看到的情况来看,这是因为我将错误的比较器导入嵌套的帮助器类以进行有序插入。但是,我已经修改了该操作,以便在创建列表时,将相同的比较器发送到helper类。然后您可以重复“二进制搜索”查找下一个bug:-)
// connect to previous and next node
Chunk<E> one = node, two = newChunk, three = node.next;
one.next = two;
two.prev = one;
two.next = three;
if (three != null)
  three.prev = two;