如何修复队列的“删除”方法

时间:2016-10-07 06:39:56

标签: java queue

我的队列使用了一个堆栈,因此我有两个堆栈.. s1接受添加,然后它的所有项目都被移动到s2,这使s2成为我的队列。

(不使用数组..)

这是我的实现,但是当我测试它时,我的删除单元测试失败。

public class Queue
{
    private Stack s1;
    private Stack s2;

    private int size;


    public Queue()
    {
        //arbitrary sized.
        s1 = new Stack();
        s2 = new Stack();

        size = 0;
    }

    public void insert(Object o)
    {
        //add object into s1.
        s1.push(o);

        size++;
    }

    //delete from queue
       public Object remove()
       {
          int n = 0; ... arbitrary size n. //size not specified
          for(int i = 1; i <= n ; i++)
         {
           //push all elements in s1 into s2 
           s2.insert(s1.pop());
         }                 

          //decrease the size
          size--;

         return s2.pop; 
       }
    public Object peekFront()
    {
        s2.push(s1.pop());


        return s2.peek();
    }


}

TEST

import org.junit.Assert;
import static org.junit.Assert.*;
import org.junit.Test;


public class QueueTest 
{
   protected Queue q;

   public QueueTest()
   {
      q = new Queue();
   }

   atTest
   public void testRemove()
       {
         assertTrue(q.isEmpty()); -- passes

         q.insert(10);
         q.insert(11);
         q.insert(12);
         q.insert(23);

         //remove
         assertEquals(10, q.remove()); --- fails

       }


   public void testPeekFront()
   {
     q.insert(80);
     q.insert(90);
     q.insert(57);

     assertEquals(20,q.peekFront());

   }
}

请你能否指出我public Object remove无法正常运作的原因......

例如,当我尝试删除23?我的测试通过,但当我测试10实际应该是,然后它失败。

以下是课程和考试的完整代码......

2 个答案:

答案 0 :(得分:0)

我认为您可能会为n提供静态值。由于值n将动态变化,请确保给出n = s1.size()[或任何自定义函数来计算大小]。请提供完整的代码。

假设修正:
 1.在删除期间,您将弹出s1中的所有元素。使它(s1)为空堆栈。所以你必须通过在remove函数本身中弹出s2中的值来填充它。正如下一个答案中提到的fabian使用辅助方法将元素从1个堆栈传输到另一个堆栈 2.在remove()方法中,将s1.pop()存储到临时变量并删除s2中的所有元素。 return temp变量。其他明智的s2将继续增长  3.设置n = s1.size();
 4. return s1.pop();

答案 1 :(得分:0)

对于工作方法,您不能简单地对大小进行硬编码。此外,您必须在下次插入之前将元素移回原始堆栈,否则订单将变为错误。我建议使用辅助方法传输对象以避免代码重复:

private static void transfer(Stack source, Stack target) {
     while (!source.isEmpty()) {
         target.push(source.pop());
     }
}

我建议懒洋洋地移动元素,以避免重复insert或重复remove操作的不必要操作:

public void insert(Object o) {
    // lazily transfer values back
    transfer(s2, s1);

    //add object into s1.
    s1.push(o);

    size++;
}

//delete from queue
public Object remove() {
    if (s1.isEmpty() && s2.isEmpty()) {
         return null; // alternative: throw exception
    }
    transfer(s1, s2);
    //decrease the size
    size--;
    return s2.pop();
}

public Object peekFront() {
    if (s1.isEmpty() && s2.isEmpty()) {
        return null; // alternative: throw exception
    }

    transfer(s1, s2);

    return s2.peek();
}

或者,您可以简单地将值传递回s1方法中的remove,这样可以使实现其他操作更简单一些,但这也会使某些操作序列效率降低。 (您还需要修复peekFront()):

//delete from queue
public Object remove() {
    if (s1.isEmpty() && s2.isEmpty()) {
         return null; // alternative: throw exception
    }
    transfer(s1, s2);

    //decrease the size
    size--;

    Object result = s2.pop();

    transfer(s2, s1);
    return result;
}