js中删除栈中间元素

问题描述 投票:0回答:1

我想获取堆栈的中间元素,所以我创建了一个函数deleteMid并递归调用remove函数来检查并弹出中间元素,但这里我得到的输出为undefined,所以请你如何纠正那个代码?代码如下。

   function deleteMid(s, sizeOfs) {
        let count = 0;
        let mid = Math.floor(sizeOfs / 2);
        remove(s, count, mid, sizeOfs);
    }

    function remove(s, count, mid, sizeOfs) {
        if (count === mid) {
            s.pop();
            return;
        }

        let num = s.pop();
        remove(s, count + 1, mid, sizeOfs);
        s.push(num);
    }
    console.log(deleteMid([1, 2, 3, 4, 5], 5))
javascript data-structures stack logic
1个回答
0
投票

您的代码工作正常,只是您不应该通过 deleteMid 输出值

returned
,而应该保留对作为参数传递给它的堆栈的引用。因此,在主程序中更改以下行:

console.log(deleteMid([1, 2, 3, 4, 5], 5));

至:

const stack = [1, 2, 3, 4, 5]; // Keep a reference to the stack
deleteMid(stack, stack.length);
console.log(stack); // Output the mutated stack

现在输出将是:

[1, 2, 4, 5]

备注

不是你的问题,而是:

  • 遗憾的是,您必须提供堆栈的长度作为单独的参数,并且在删除之后,您无法从函数中获得调整后的大小。数组有一个

    length
    属性,所以你可以使用它。如果这是一个不允许您使用
    length
    属性的作业,则创建一个维护
    Stack
    属性的
    size
    类。

  • 您的

    remove
    函数参数太多。它不需要
    sizeOfs
    :除了将其传递给递归调用之外,它从不使用它。

  • 您可以将

    count
    传递给递归调用,而不是使用
    mid-1
    参数(它会增加)。这会保存另一个参数。

  • 对于整数除以 2,使用

    >>
    运算符而不是
    Math.floor
    更优雅。

  • 数组有一个

    splice
    方法可以完成这项工作。但我想这是一个作业,要求您不要使用除
    push
    pop
    之外的任何数组方法。

  • 变量名称

    s
    表明它是一个字符串。相反,请使用更具描述性的名称,例如
    stack

  • 您的

    remove
    方法有两个地方调用
    pop
    。这可以在一个地方完成,将早期出口移到它之后。

这是您的代码,其中考虑了上述一些注释:

function deleteMid(stack, stackSize) {
    // Use bitshift to integer-divide by 2.
    // Don't pass count, nor sizeOfs as argument
    remove(stack, stackSize >> 1); 
}

function remove(stack, indexFromTop) {
    const value = stack.pop();
    if (indexFromTop == 0) { // Base case exit moved after the pop call. 
        return;
    }
    remove(stack, indexFromTop - 1);
    stack.push(value);
}

const stack = [1, 2, 3, 4, 5];
deleteMid(stack, 5);
console.log(stack);

为了使更改后的堆栈大小可供调用者使用,并防止调用者使用除

push
pop
之外的任何其他数组属性,您可以定义一个
Stack
类,如下所示:

/* Define a class so that you can enforce that no Array properties other than
 * push and pop can be used, and that you can maintain a size that is also 
 * available after deleting elements
 */ 
class Stack { 
    #stack; // Private array property so caller cannot access it nor its methods
    
    constructor(...values) {
        this.#stack = values;
    }
    // Only expose the stack-related methods
    get length() {
        return this.#stack.length;
    }
    push(value) {
        this.#stack.push(value);
    }
    pop() {
        return this.#stack.pop();
    }
    // Custom methods:
    deleteMid() {
        // Use bitshift to integer-divide by 2.
        // Don't pass count, nor sizeOfs as argument
        this.remove(this.length >> 1); 
    }
    remove(indexFromTop) {
        const value = this.pop();
        if (indexFromTop == 0) { // Base case exit moved after the pop call. 
            return;
        }
        this.remove(indexFromTop - 1);
        this.push(value);
    }
    // To help printing the stack (or for other purposes), 
    //    make the stack iterable
    *[Symbol.iterator]() {
        yield* this.#stack;
    }
}

const stack = new Stack(1, 2, 3, 4, 5);
stack.deleteMid();
console.log(...stack); // Use iterator to print the stack's values

© www.soinside.com 2019 - 2024. All rights reserved.