MST

星途 面试题库

面试题:JavaScript 类数组对象转换后的使用及性能考量

假设你将一个较大的类数组对象转换为数组后,需要对其进行频繁的插入和删除操作。从性能角度考虑,你会选择使用普通数组还是其他数据结构(如果有)?阐述原因,并结合代码说明如何利用 JavaScript 特性优化这些操作。
16.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

从性能角度考虑,对于频繁的插入和删除操作,不建议使用普通数组,而是选择 LinkedList(链表)这种数据结构。

原因:普通数组在插入或删除元素时,尤其是在数组中间位置操作时,需要移动大量元素以保持连续性,时间复杂度为 $O(n)$。而链表插入和删除元素仅需修改指针指向,时间复杂度为 $O(1)$。

JavaScript 没有内置的链表数据结构,但可以通过对象模拟链表:

// 模拟链表节点
function ListNode(val) {
    this.val = val;
    this.next = null;
}

// 模拟链表
function LinkedList() {
    this.head = null;
    this.tail = null;

    // 插入到链表尾部
    this.addToTail = function(val) {
        const newNode = new ListNode(val);
        if (!this.head) {
            this.head = newNode;
            this.tail = newNode;
        } else {
            this.tail.next = newNode;
            this.tail = newNode;
        }
    };

    // 删除指定值的节点
    this.deleteNode = function(val) {
        let current = this.head;
        let prev = null;
        while (current) {
            if (current.val === val) {
                if (prev === null) {
                    this.head = current.next;
                } else {
                    prev.next = current.next;
                }
                if (current === this.tail) {
                    this.tail = prev;
                }
                return;
            }
            prev = current;
            current = current.next;
        }
    };
}

使用示例:

const list = new LinkedList();
list.addToTail(1);
list.addToTail(2);
list.addToTail(3);
list.deleteNode(2);

如果非要使用数组,可以利用 JavaScript 的 splice 方法,但要尽量避免在数组中间频繁操作。例如在数组头部插入元素:

let arr = [1, 2, 3];
arr.unshift(0); // 在头部插入元素,时间复杂度 O(n),但比在中间插入性能好

在尾部插入元素使用 push,时间复杂度为 $O(1)$:

arr.push(4);

删除元素使用 pop(删除尾部元素)或 shift(删除头部元素),时间复杂度为 $O(1)$:

arr.pop();
arr.shift();

如果要删除指定位置元素,使用 splice,但尽量减少在中间位置删除操作:

arr.splice(1, 1); // 删除索引为1的元素