cuicui.
返回全部文章
Web前端 共约 195 字 预计阅读 1 分钟

数据结构学习-队列

队列是什么

队列是一种特殊的线性表, 他只允许在表的前端进行删除操作, 在表的后端进行插入操作

只有最早进入队列的元素才能最先从队列中删除, 所以队列又称为 先进先出线性表 (FIFO)

队列的实现

数组实现的队列

class arrQueue {
    private queue: unknown[] = [];

    // 从队列尾部插入元素
    enqueue(data: unknown) {
        return this.queue.push(data);
    }

    // 从队列头部删除元素
    dequeue() {
        return this.queue.shift();
    }

    // 返回队列头部元素
    front() {
        return this.queue.at(0);
    }

    isEmpty() {
        return this.queue.length === 0;
    }
    size() {
        return this.queue.length;
    }
    clear() {
        this.queue = [];
    }
    toString() {
        return this.queue.join("-");
    }
}

const queue = new arrQueue();

数组实现的队列虽然简单, 但是由于 shift 操作消耗资源大, 所以这种队列性能不高

对象实现的队列

type QueueObj = {
    [k: number]: any;
};
// 使用对象实现
class objectQueue {
    private queue: QueueObj = {};
    // 开始的下标
    private start = 0;
    // 结束的下标
    private end = 0;

    // 从队列尾部插入元素
    enqueue(data: unknown) {
        this.queue[this.end] = data;
        this.end++;
        return this.queue[this.end - 1];
    }

    // 从队列头部删除元素
    dequeue() {
        if (this.size() > 0) {
            let item = this.queue[this.start];
            delete this.queue[this.start];
            this.start++;
            return item;
        } else return undefined;
    }

    // 返回队列头部元素
    front() {
        return this.queue[this.start];
    }

    isEmpty() {
        return this.size() === 0;
    }
    size() {
        return this.end - this.start;
    }
    clear() {
        this.queue = {};
        this.start = 0;
        this.end = 0;
    }
    toString() {
        let str = "";
        for (let index = this.start; index < this.end; index++) {
            str += this.queue[index] + " ";
        }
        return str;
    }
}

双端队列

双端队列(Double-ended queue,简称 deque)是一种具有队列和栈的性质的数据结构,它允许从两端添加和删除元素。

实现:

type DoubleQueue = {
    [k: number]: any;
};
// 使用对象实现
class doubleQueue {
    private queue: DoubleQueue = {};
    // 开始的下标
    private start = 0;
    // 结束的下标
    private end = 0;

    // 从队列头部添加元素
    addFront(data: any) {
        this.start--;
        this.queue[this.start] = data;
        return this.queue[this.start];
    }
    // 从队列尾部插入元素
    addBack(data: unknown) {
        this.queue[this.end] = data;
        this.end++;
        return this.queue[this.end - 1];
    }
    // 从队列头部删除元素
    delFront() {
        if (this.size() > 0) {
            const item = this.queue[this.start];
            delete this.queue[this.start];
            this.start++;
            return item;
        } else return undefined;
    }

    // 从队列尾部删除元素
    delBack() {
        if (this.size() > 0) {
            const item = this.queue[this.end - 1];
            delete this.queue[this.end - 1];
            this.end--;
            return item;
        } else return undefined;
    }

    // 返回队列头部元素
    peekFront() {
        return this.queue[this.start];
    }
    // 返回队列尾部元素
    peekBack() {
        return this.queue[this.end - 1];
    }

    isEmpty() {
        return this.size() === 0;
    }
    size() {
        return this.end - this.start;
    }
    clear() {
        this.queue = {};
        this.start = 0;
        this.end = 0;
    }
    toString() {
        let str = "";
        for (let index = this.start; index < this.end; index++) {
            str += this.queue[index] + " ";
        }
        return str;
    }
}

队列的应用

击鼓传花游戏

// 击鼓传花游戏
function game(list: Array<string>, num: number) {
    let queue = new objectQueue();
    // 先把人员入栈
    for (let i = 0; i < list.length; i++) {
        queue.enqueue(list[i]);
    }

    // 停止条件是 队列中只有一个元素
    while (queue.size() > 1) {
        for (let i = 0; i < num; i++) {
            // 将队列头部的元素添加到队尾
            queue.enqueue(queue.dequeue());
        }
        // 循环结束队头的就是出局者
        console.log(queue.dequeue() + "淘汰了");
    }
    // 只有一个元素的话 这就是获胜者
    console.log(queue.dequeue() + "胜利");
}

game(["tim", "tom", "jack", "nana", "tina"], 7);

检查回文数 (双端队列)

// 回文数检查
function check(str: string) {
    // 全部转小写, 去掉空格
    str = str.toLocaleLowerCase().split(" ").join("");
    console.log("处理后的字符串:" + str);
    // 将字符串加入队列
    const que = new doubleQueue();
    for (let i = 0; i < str.length; i++) {
        que.addBack(str[i]);
    }
    let tag = true;
    // 取出首尾元素进行对比
    while (que.size() > 1) {
        if (que.delFront() != que.delBack()) {
            tag = false;
            break;
        }
    }
    console.log(tag);
}

check("abc dc bA");