js-实现数据结构-队列

前言

      前面讲过使用js模拟栈的算法,今天主要讲,使用js模拟队列的算法,为什么要这样做呢?说实话是闲的无聊,现在处于一个项目空档期,为了不至于太无聊,就想把数据结构里面的算法都使用js模拟一遍。

队列

1、什么是队列?

      想象中午食堂吃饭时、等电梯时、早晚高峰进地铁时,都需要排队。那么肯定是先排队的有优先权,然后依次进入。队列也是这个道理,只有一个出口,一个入口,特点是先进先出,这和栈的思想相反。明白了队列的特点,分析如何使用js实现队列?
      队列有一个入口,取名为enqueue;出口取名为dequeue;正常情况下,还需要读取队首和队尾元素,命名为frontback,读取队列所有元素,命名为toStringData, 判断队列是否空,命名为isEmpty。现在可以完成队列的构造函数了,如下:

function Queue() {
    this.data = [];
    this.enqueue = enqueue;  //队尾添加一个元素
    this.dequeue = dequeue;  //队首删除一个元素
    this.front = front;  //读取队首元素
    this.back = back;  //读取队尾元素
    this.toStringData = toStringData;  //显示队内元素
    this.isEmpty = isEmpty;  //判断队列是否为空
}
2、使用enqueue()方法,在队尾添加一个元素,如下:
function enqueue(element) {
    this.data.push(element);
}
3、使用dequeue()方法,在队首删除一个元素,并返回删除的值,如下:
function dequeue() {
    return this.data.shift();
}
4、使用front()方法,返回队首元素,如下:
function front() {
    return this.data[0];
}
5、使用back()方法,返回队尾元素,如下:
function back() {
    return this.data[this.data.length - 1];
}
6、使用toStringData()方法,返回队列元素,如下:
function toStringData() {
    let queueString = '';
    for (let i = 0; i < this.data.length; i++) {
        queueString += this.data[i] + '\n';
    }

    return queueString;
}
7、使用isEmpty()方法,判断队列是否为空,如下:
function isEmpty() {
    return this.data.length === 0;
}

      到这里,就使用js实现了一个单向队列。

实例

1、使用队列进行排序(基数排序)

      首先介绍下什么是基数排序,基数排序又叫分配式排序桶子法,它是通过数据的部分信息,将要排序的元素分配至中,以达到排序的作用。
      假设有一串数值,如下所示:

98、25、31、10、99、81、65、42、51

      首先根据个位数的数值,在走访数值时将它们分配至编号0到9的桶子中:

0: 10
1: 31 81 51
2: 42
3:
4:
5: 25 65
6:
7:
8: 98
9: 99

      接下来将这些桶子中的数值串接起来,如下所示:

10 31 81 51 42 25 65 98 99

      接着根据十位数在进行一次分配,如下所示:

0:
1: 10
2: 25
3: 31
4: 42
5: 51
6: 65
7:
8: 81
9: 98 99

      接下来将这些数值串接起来,形成以下数值:

10 25 31 42 51 65 81 98 99

      这时候排序已经完成;如果有三位数或这更高位数,则持续进行以上动作,直至最高位为止。

      如何使用队列的思想进行排序呢?假设是0~99间的数进行比较,首先需要比较个位数,因为数值在0~99之间,只需对数进行取余,即可得到个位数,对数值除以10,向下取整可得到十位数。到这儿开始使用队列()进行存值,需要是个队列分别存储0~9的值。如下:

/**
 *  @param nums 初始数组
 *  @param queue 队列数组
 *  @param n 几位数
 *  @param digit 个位数或十位以上的数
 * */
function distribute (nums, queue, n, digit) {
    for (let i = 0; i < n; i++) {
        if (digit === 1) {
            queue[nums[i] % 10].enqueue(nums[I]);
        } else {
            queue[Math.floor(nums[i] / 10)].enqueue(nums[I]);
        }
    }
}

      基数排序后展示函数,如下:

/**
 *  @param queues 队列数组
 *  @nums nums 初始数组
 * */
function showAfterData (queues, nums) {
    let i = 0;
    for (let digit = 0; digit < 10; ++digit) {
        while (!queues[digit].isEmpty()) {
            nums[i++] = queues[digit].dequeue();
        }
    }
    return nums;
}

      完成算法后,随机来点数实验下,如下:

let queues = [];
for (let i = 0; i < 10; ++i) {
    queues[i] = new Queue();
}
let nums = [];
for (let i = 0; i < 10; ++i) {
    nums[i] = Math.floor(Math.floor(Math.random() * 101));
}
console.log('个位数排序:');
distribute(nums, queues, 10, 1);
console.log(collect(queues, nums));

console.log('十位数排序:');
distribute(nums, queues, 10, 10);
console.log(collect(queues, nums));

      结果如下:


基数排序结果

双向队列

      双向队列即队列的首尾都能进能出,那么只需在单向队列中添加两个方法,队首添加一个元素方法(fenqueue),队尾删除一个元素的方法('bdequeue'),即可.
      队列的构造函数添加两个方法,如下:

 function Queue() {
     this.data = [];
     this.enqueue = enqueue;  //队尾添加一个元素
     this.dequeue = dequeue;  //队首删除一个元素
     `this.fenqueue = fenqueue;  //队首添加一个元素`
     `this.bdequeue = bdequeue;  //队尾删除一个元素`
     this.front = front;  //读取队首元素
     this.back = back;  //读取队尾元素
     this.toStringData = toStringData;  //显示队内元素
     this.isEmpty = isEmpty;  //判断队列是否为空
 }

function fenqueue (element) {
    this.data.unshift(element);
}

function bdequeue () {
    return this.data.pop();
}

      现在就完成了双向队列。双向队列能实现什么功能呢?如回文之类的使用双向队列能很方便的实现,思想如上一片文章中的栈,使用双向队列无论从前还是后插入数据,都一个原理。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容