为什么我用Java双链表实现的队列不满足FIFO先进先出特性?
问题根因分析
- 核心逻辑不符合队列FIFO规则:队列要求尾插头删,你当前的实现是「头插头删」,完全符合栈的后进先出(LIFO)规则,这是输出和预期相反的核心原因。
你调用enqueue依次插入first、second、third、fourth时,每次都把新节点放在链表头部,最终头部存储的是最后插入的fourth,出队时从头部删除自然先返回fourth、再返回third。 enqueue方法存在两处细节bug:- 新节点插入头部时,没有给新节点的
next属性赋值为原来的firstNode,链表前后指针链接不完整 numberOfElement++仅写在非空分支,插入第一个元素时不会更新计数,会导致后续计数逻辑错误
- 新节点插入头部时,没有给新节点的
dequeue方法存在计数bug:numberOfElement--仅写在多元素分支,删除最后一个元素时不会更新计数
修复方案
将入队逻辑修改为尾插,同时修复所有细节bug即可符合队列预期:
public void enqueue(T newEntry){ // T as generic type Node<T> newNode = new Node(newEntry,null,null); // Node(T element, Node prev,Node next) if(isEmpty()){ firstNode = newNode; lastNode = newNode; } else { // 新节点追加到链表尾部 lastNode.next = newNode; newNode.prev = lastNode; lastNode = newNode; } // 计数逻辑统一放到分支外,避免空队列插入时漏更 numberOfElement++; } public T dequeue(){ if(isEmpty()){ throw new NullPointerException("Queue is empty"); } T removedElement = firstNode.element; if(firstNode == lastNode){ // 只剩一个元素,直接清空首尾指针 firstNode = null; lastNode = null; } else { // 移除头部节点,更新头部指针 firstNode = firstNode.next; firstNode.prev = null; } // 计数减一统一处理 numberOfElement--; return removedElement; }
修复后执行测试代码,输出就会是预期的first、second。
内容的提问来源于stack exchange,提问作者itakez
相关产品推荐
相关产品推荐

