1

我试图将 Index 元素移动到单个列表的末尾,同时移动所有其他元素,所以如果我有一个 {1,2,3,4,5} 列表并将索引 2 传递给它,它将返回 { 1、2、4、5、3}。

public void moveToLast(int index) throws IllegalArgumentException {
  if(index<0 || index > size())
        throw new IllegalArgumentException("" + index);
  Node ref= first;
  Node otherRef=first;
  for(int i=0;i<index;i++){
      ref=ref.next;
      for(int j=0;j<size()-1;j++){
          if(otherRef.next!=null)
              otherRef=otherRef.next;
      }   
  }
  E temp=ref.data;
  ref.data=otherRef.data;
  otherRef.data=temp;

}

我写的这段代码只切换索引处的元素和最后一个元素,返回 {1, 2, 5, 4, 3}

感谢您的帮助并记住,我对编码非常陌生,非常感谢所有帮助。

4

2 回答 2

1

您必须在循环时更新引用,而不是在最后。

这是一个小算法,可以为您节省双循环。我实现了它交换引用,而不是data,但结果没有实际差异。我不确定您对一种方法或另一种方法有什么限制,但是如果您有删除节点等的方法,您通常使用引用而不是值。

我没有编译它,所以请原谅任何错误,但我认为这样的事情应该可以工作:

public void moveToLast(int index) throws IllegalArgumentException {
    if(index<0 || index > size())
        throw new IllegalArgumentException("" + index);
    Node refToMove= first;
    Node previousRef=null;
    for(int i=0;i<index && refToMove!=null;i++){
        previousRef=refToMove;
        refToMove=refToMove.next;
    }
    if(refToMove!=null && previousRef!=null) {
           Node nextRef=refToMove.next;
           while(nextRef!=null) {
               previousRef.next = nextRef;
               Node tempRef = nextRef.next;
               nextRef.next = refToMove;
               refToMove.next = tempRef;
               nextRef = tempRef;
           }
    }

}

于 2013-06-20T23:24:43.833 回答
0

也考虑一下。

if(index<0 || index > size())

不会捕获所有错误索引。如果index == size不应该被允许,因为将超出范围,并且如果索引是最后一个元素,那么您应该返回,因为不需要做任何事情,也许更改为

if(index<0 || index >= size())
   //throw exception
if( index == (size()-1))
   return

就像您说的那样,您的代码仅在您找到索引元素结束最后一个元素并在最后分配它们时交换。

您需要做的是找到第一个,然后为每个设置链接到下一个元素,直到最后,然后设置最后一个元素以链接原始索引,如下所示

public void moveToLast(int index) throws IllegalArgumentException {
    if(index<0 || index >= size())
       throw new IllegalArgumentException("" + index);
    if( index == (size()-1))
       return
    Node currentElement = first;
    Node elementToMove;
    Node nextElement;
    // if first is the one to move
    if(index == 0)
    { 
        elementToMove = first;
        currentElement = first.next;
        first = currentElement
    }
    // Iterate over the list only once
    for(int i = 0; i < size()-2; i++)  // up to the 2nd to last element as the next element is referenced
    {
         nextElement = currentElement.next
         if(i+1 == index) // next element is the one you want to move
         {
              // store reference to the element you want to move
              elementToMove = nextElement;
              // Skip this element and update to the next one
              nextElement = nextElement.next;
         }
         // Update reference
         currentElement.next = nextElement;
         // Move to next element
         currentElement = nextElement
    }
    // Put the one to move on the end
    currentElement.next = elementToMove
}

这使您不必在列表中循环两次,我没有检查或遵守这一点,因此您可能还需要在此处添加空检查,如果输入的索引为 0,您还需要特别考虑,即您需要重置first

于 2013-06-20T23:53:47.200 回答