当它应该只出列一个节点时,出列似乎一次完成8个节点



我正在尝试将列表中的顶部节点出列,并将其分配给一个变量。

在这个小提琴中,x应该刚好等于2,但它等于3到10。

var Node = function(_content) { //makes the object node
this.content = _content; // contains the contents of the node
this.next = null; // pointer that points to the node infront of it
this.last = null; // pointer that points to the node behind it
this.ID = null;
}
function Queue() {
this.top = null; //head of the list 
this.bottom = null; //tail of the list
this.length = 0; // length set to zero
this.toString = function() { // turns objects into strings
var str = ""; //creates the string that the content will be passed to
var node = this.top; //makes the node it checks the node at the top of the list
while (node != null) { //goes through each node
str += node.content; //puts contents of node into str
node = node.next; //sets current node to the next node
}
return str; //returns a string of all the content
}
this.enqueue = function(_content) { // adds a node to the back of the queue
var newNode = new Node(_content); //creates a node with the content that was passed through
if (this.length === 0) { //checks the length to see if its zero
this.top = this.bottom = newNode; //this tells the queue that this node is both the top and bottom
} else {
this.bottom.next = newNode;
this.bottom = newNode; //makes new node the bottom
}
this.ID++;
this.length++; //the length of the queue will increase by 1 every time a new node is added
return this;
}
this.dequeue = function() { //takes a node off the top of the queue
if (!this.bottom) return this; //if there are no nodes at the top it will return itself
if (this.length === 0 || this.top === this.bottom) { //checks if its at the last node
this.top = null; //sets the top to null
this.bottom = null; //sets the bottom to null
} else {
this.top = this.top.next; //sets this node to be equal to the next node on the queue
}
this.ID--;
this.length--; //decreases the length by one each time a node is removed
return this;
}
this.getLength = function() {
return this.length
}
this.peek = function() {
return this.top && this.top.content;
}
this.hasElements = function() {
if (this.length > 0)
return true
else
return false
}
this.topElem = function(_content) {
return this.top.content;
}
this.getID = function(_content) {
return this.ID.content;

}
}
function main() { //happens when user clicks button
var n = document.getElementById("value").value; //it grabs the input
debugger;
var q1 = createQ1(n); //creates the first queue using a unique function
var q2 = new Queue(); //creates the second function using the standard function
//adds debugging functionality
printQueue(q1, 0, 1); //calls the printing function
printQueue(q2, 0, 2); //calls the printing function
sieveAlgorithm(q1, q2);
}
function createQ1(n) { //creates the queue 1
var myQueueOne = new Queue(); //creates an empty queue
for (i = 2; i <= n; i++) //adds to the queue up to n starting from 2
//  parseInt(i);
myQueueOne.enqueue(i); //adds all the numbers to the queue
return myQueueOne; // returns numbers to q1
}
function printQueue(qList, itr, qnumber) { //function for printing out the queue. qlist = the queue, itr = iteration, qnumber = 1 since we passed it through
var string = ""; //creates empty string
if (qnumber == 1) { //creates the template
string = "Iteration " + itr + ": Q1 = ";
string = string + " " + qList;
} else {
string = "  Q2 = "
string = string + qList;
}
var header = document.createElement("h3");
var t;
if (qnumber == 1) {
var att = document.createAttribute("id");
att.value = "itr" + itr;
header.setAttributeNode(att);
t = document.createTextNode(string);
header.appendChild(t);
document.getElementById("output").appendChild(header);
} else {
document.getElementById("itr" + itr).innerHTML = document.getElementById("itr" + itr).innerHTML + string;
}
}
function sieveAlgorithm(q1, q2) {
var counter = 1;
var lengthOfq1 = q1.getLength();
var x = q1.dequeue();
q2.enqueue(x);
document.getElementById("output2").innerHTML = x;
printQueue(q1, 1, 1);
printQueue(q2, 1, 2);
}
<input type="textbox" id="value" value="10" />
<input type="button" id="push" value="Add N" onclick="main()" />
<br><br><br>
<p id="output"></p>
<p id="output2"></p>

问题是,您希望dequeue方法返回出队列的值,但它没有返回,而是返回队列本身(return this(。

因此,要么更改dequeue返回的内容,要么使用peek方法在实际执行操作之前获取将要出列的值

var x = q1.dequeue();
q2.enqueue(x);

这个:

var x = q1.peek();
q1.dequeue();
q2.enqueue(x);

备注

  • 使用类语法
  • 节点不需要双重链接。一个单独的链表对于一个队列来说就足够了
  • 使Queue可迭代——这使toString成为一个简单的方法
  • 不要使用明显的评论,比如";检查长度以查看其是否为零;。注释应该在更高的层次上解释事情,而不仅仅是用英语翻译代码
  • dequeue中,条件this.length === 0永远不会为真,因为前面的if已经处理过这种情况
  • 不要使用模式:if <boolean expression> return true; else return false。相反,只返回布尔表达式
  • topElem方法不应具有参数。目标是返回内容,而不是获取它
  • 不要把I/O和类混在一起。该类应该只提供toString方法,但不应该创建DOM元素。将I/O与算法问题分开

以下是如何处理以上几点。此代码不使用HTML,它只是使用n=10运行测试并将结果输出到控制台:

class Node { // Use class syntax
constructor(content) {
this.content = content;
this.next = null; // In a queue there is no need for a link to previous node.
}
}
class Queue {
constructor(...values) { // Allow caller to already specify content for queue
this.top = null; 
this.bottom = null;
this.length = 0;
// Populate the queue with any values that were provided
for (const content of values) {
this.enqueue(content);
}
}
* [Symbol.iterator]() { // Make queue iterable -- handy for toString
let node = this.top;
while (node) {
yield node.content;
node = node.next;
}
}
toString() { // Make use of above iterator
return Array.from(this).join("->") || "(empty)";
}
enqueue(content) {
const newNode = new Node(content);
if (this.length === 0) { 
this.top = this.bottom = newNode;
} else {
this.bottom.next = newNode;
this.bottom = newNode;
}
this.length++;
return this;
}
dequeue() {
if (this.length === 0) return null; // Don't return `this`
const content = this.top.content;
if (this.top === this.bottom) {
this.top = this.bottom = null;
} else {
this.top = this.top.next;
}
this.length--;
return content; // Return the value, not the queue
}
peek() {
return this.top?.content; // Use the optional chaining operator
}
hasElements() {
return this.length > 0;
}
topElem(_content) {
return this.top.content;
}
}
function main() {
const n = 10;
// Create the values on the fly and pass them to the constructor
const q1 = new Queue(...Array.from({length: n - 1}, (_, i) => i + 2));
const q2 = new Queue();
console.log("Q1 is " + q1);
console.log("Q2 is " + q2);
// Now dequeue provides the content that was removed from the queue
q2.enqueue(q1.dequeue());
console.log("after moving one value:");
console.log("Q1 is " + q1);
console.log("Q2 is " + q2);
}
main();

最新更新