当前位置 博文首页 > 司夏的博客:JavaScript 数据结构与算法(队列)

    司夏的博客:JavaScript 数据结构与算法(队列)

    作者:[db:作者] 时间:2021-07-29 09:44

    队列数据结构

    队列是遵循先进先出(FIFO,也称为先来先服务)原则的一组有序的项。队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。在现实中,最常见的队列的例子就是排队。

    创建队列

    创建自己的类来表示一个队列。首先需要一个用于存储队列中元素的数据结构。可以使用数组,但是,为了写出一个在获取元素时更高效的数据结构,将使用一个对象来存储元素。

    // 声明类
    class Queue {
        constructor() {
            this.count = 0; //  count 属性来帮助我们控制队列的大小
            this.lowestCount = 0; // 追踪第一个元素
            this.items = {}; 
        }
    }
    

    向队列添加元素

    enqueue(element(s)):向队列尾部添加一个(或多个)新的项。

    enqueue(element) {
        this.items[this.count] = element; // 要把 count 变量作为 items对象中的键,对应的元素作为它的值
        this.count++;
    }
    

    从队列移除元素

    dequeue():移除队列的第一项(即排在队列最前面的项)并返回被移除的元素。

    dequeue() {
        if (this.isEmpty()) {
            return undefined;
        }
        const result = this.items[this.lowestCount]; // {1} 
        delete this.items[this.lowestCount]; // {2} 
        this.lowestCount++; // {3} 
        return result; // {4} 
    }
    

    查看队列头元素

    peek():返回队列中第一个元素。队列不做任何变动(不移除元素,只返回元素信息)

    peek() {
        if (this.isEmpty()) {
            return undefined;
        }
        return this.items[this.lowestCount];
    }
    

    检查队列是否为空并获取它的长度

    isEmpty():如果队列中不包含任何元素,返回 true,否则返回 false。

    isEmpty() {
        return this.count - this.lowestCount === 0;
        // 只需要计算 count 和 lowestCount 之间的差值即可
    }
    

    size():返回队列包含的元素个数,与数组的 length 属性类似。

    size() {
        return this.count - this.lowestCount;
    }
    

    清空队列

    clear():要清空队列中的所有元素

    clear() {
        this.items = {};
        this.count = 0;
        this.lowestCount = 0;
    }
    

    创建 toString 方法

    toString() {
        if (this.isEmpty()) {
            return '';
        }
        let objString = `${this.items[this.lowestCount]}`;
        for (let i = this.lowestCount + 1; i < this.count; i++) {
            objString = `${objString},${this.items[i]}`;
        }
        return objString;
    }
    

    完整的 Queue 类

    class Queue {
        constructor() {
            this.count = 0;
            this.lowestCount = 0;
            this.items = {};
        };
        enqueue(element) {
            this.items[this.count] = element;
            this.count++;
        };
        dequeue() {
            if (this.isEmpty()) {
                return undefined
            }
            const result = this.items[this.lowestCount];
            delete this.items[this.lowestCount];
            this.lowestCount++;
            return result;
        };
        peek() {
            if (this.isEmpty()) {
                return undefined;
            }
            return this.items[this.lowestCount]
        };
        isEmpty() {
            return this.size() === 0;
        };
        size() {
            return this.count - this.lowestCount;
        };
        clear() {
            this.count = 0;
            this.lowestCount = 0;
            this.items = {};
        };
        toString() {
            if (this.isEmpty()) {
                return '';
            }
            let objString = `${this.items[this.lowestCount]}`;
            for (let i = this.lowestCount + 1; i < this.count; i++) {
                objString = `${objString},${this.items[i]}`;
            }
            return objString;
        }
    }
    

    使用 Queue 类

    首先实例化创建的 Queue 类

    const queue = new Queue(); 
    console.log(queue.isEmpty()); // 输出 true
    

    添加一些元素(可以向队列添加任何类型的元素)

    queue.enqueue('John'); 
    queue.enqueue('Jack'); 
    console.log(queue.toString()); // John,Jack 
    
    queue.enqueue('Camila'); 
    console.log(queue.toString()); // John, Jack, Camila 
    console.log(queue.size()); // 输出 3 
    console.log(queue.isEmpty()); // 输出 false 
    
    queue.dequeue(); // 移除 John 
    queue.dequeue(); // 移除 Jack 
    console.log(queue.toString()); // Camila
    

    双端队列数据结构

    双端队列(deque,或称 double-ended queue)是一种允许我们同时从前端和后端添加和移除元素的特殊队列。双端队列同时遵守了先进先出和后进先出原则,可以说它是把队列和栈相结合的一种数据结构。,双端队列的一个常见应用是存储一系列的撤销操作。

    创建 Deque 类

    class Deque {
        constructor() {
            this.count = 0;
            this.lowestCount = 0;
            this.items = {};
        };
        //方法
    }
    

    双端队列是一种特殊的队列,所以构造函数中的部分代码和队列相同,包括相同的内部属性和以下方法:isEmpty、clear、size 和 toString。由于双端队列允许在两端添加和移除元素,还会有下面几个方法。

    向双端队列的前端添加元素

    addFront(element):该方法在双端队列前端添加新的元素。

    要将一个元素添加到双端队列的前端,存在三种场景。

    addFront(element) {
    	// 第一种场景是这个双端队列是空的(行{1})执行 addBack 方法,元素会被添加到双端队列的后端.
        if (this.isEmpty()) { // {1} 
            this.addBack(element);
        } else if (this.lowestCount > 0) { // {2} 
        //第二种场景是一个元素已经被从双端队列的前端移除(行{2}),也就是说 lowestCount 属性会大于等于 1。
    	//这种情况下,我们只需要将 lowestCount 属性减 1 并将新元素的值放在这个键的位置上即可。
            this.lowestCount--;
            this.items[this.