手记

JavaScript实现 栈和队列

创建一个类来表示栈:
function Stack () {
    var items = []; //选择数组来保存栈里的元素

    this.push = function (element) {//这个方法负责往栈里添加新元素(只添加到栈顶)
        items.push(element);
    };

    this.pop = function () {//这个方法主要用来移除栈里的元素(遵从先进后出)
        return items.pop();
    };

    this.peek = function () {//这个方法负责返回栈顶的元素
        return items[items.length - 1];
    };

    this.isEmpty = function () {//如果栈为空的话返回true,否则就返回false
        return items.length == 0;
    };

    this.size = function () {//这个方法返回栈的长度
        return items.length;
    };

    this.clear = function () {//这个方法用来移除栈里的所有元素,把栈清空
        items = [];
    };

    this.print = function () {
        console.log(items.toString());//把栈里的元素都输出到控制台
    }
}

通过使用Stack类来解决一些问题,如将十进制数转为二进制数:

function divideBy2 (decNumber) {
    var remStack = new Stack();
    var rem = 0, binaryString = '';

    while (decNumber > 0) {
        rem = Math.floor(decNumber % 2);
        remStack.push(rem);
        decNumber = Math.floor(decNumber / 2);
    }

    while (!remStack.isEmpty()) {
        binaryString += remStack.pop().toString();
    }
    return binaryString;
}

修改上面代码,就可实现将十进制数转为其他进制的数:

function baseConverter (decNumber, base) {
    var remStack = new Stack();
    var rem = 0, baseString = '', digits = '0123456789ABCDEF';

    while (decNumber > 0) {
        rem = Math.floor(decNumber % base);
        remStack.push(rem);
        decNumber = Math.floor(decNumber / base);
    }

    while (!remStack.isEmpty()) {
        /*
         *十进制转二进制,余数是0或1;十进制转八进制,余数是0到7;
         *十进制转十六进制,余数是0到9加上A、B、C、D、E、F
         */
        baseString += digits[remStack.pop()];
    } 
    return baseString;
}

创建一个类来表示栈:

function Queue () {
    var items = [];

    this.enqueue = function (element) {//负责向队列添加新元素
        items.push(element);
    };

    this.dequeue = function () {//从队列中移除第一个元素
        return items.shift();
    };

    this.front = function () {//返回队列最前面的项
        return items[0];
    };

    this.isEmpty = function () {//如果队列为空,返回true,否则返回false
        return items.length == 0;
    };

    this.size = function () {//返回队列到长度
        return items.length;
    };

    this.print = function () {//把队列里的元素都输出到控制台
        console.log(items.toString());
    };
}

创建优先队列:(优先队列 元素的添加和删除是基于优先级的)

function PriorityQueue () {
    var items = [];

    function QueueElement (element, priority) {//创建这个特殊的元素,用来包含要添加到队列的元素
        this.element = element;
        this.priority = priority;
    }

    this.enqueue = function (element, priority) {
        var queueElement = new QueueElement(element, priority);

        if (this.isEmpty()) {
            items.push(queueElement);//如果队列为空,直接将元素入列,否则就需要比较该元素与其他元素的优先级
        } else {
            var added = false;

            for (var i = 0; i < items.length; i++) {
                /*
                当找到一个比要添加的元素的priority值更大(优先级更低)的项时,就把新元素
                插入到它之前(对于优先级相同,但是先添加到队列的元素,同样遵循先进先出的原则)
                */
                if (queueElement.priority < items[i].priority) {
                    items.splice(i, 0, queueElement);//一旦找到priority值更大的元素,就插入新元素
                    added = true;
                    break;
                }
            }
            if (!added) {//如果要添加的元素的priority值大于任何已有的的元素,把它添加到队列的末尾
                items.push(queueElement);
            }
        }
    };

    this.dequeue = function () {
        return items.shift();
    };

    this.front = function () {
        return items[0];
    };

    this.size = function () {
        return items.length;
    };

    this.isEmpty = function () {
        return items.length == 0;
    };

    this.print = function () {
        // console.log(items.toString());
        console.log(items);

    };
}   
var priorityQueue = new PriorityQueue();
priorityQueue.enqueue('John', 2);
priorityQueue.enqueue('Jack', 1);
priorityQueue.enqueue('Camila', 1);
priorityQueue.print();

在下图中可以看到每条命令的结果:

这里实现的优先队列称为 最小优先队列,因为优先级的值较小的元素被放置在队列最前面。最大优先队列则与之相反。
<br>
创建一个循环队列,并用循环队列实现一个击鼓传花的小应用:

function hotPotato (nameList, num) {
    var queue = new Queue();//要用到实现的Queue类

    for (var i = 0; i < nameList.length; i++) {
        queue.enqueue(nameList[i]);
    }

    var eliminate = '';
    while (queue.size() > 1) {
        for (var i = 0; i < num; i++) {
            queue.enqueue(queue.dequeue());//队列开头移除一项,再将其添加到队列末尾
        }
        eliminate = queue.dequeue();//一旦传递次数达到给定的数字,拿着花的人就被淘汰了(从队列末尾移除)
        console.log(eliminate + '在击鼓传花游戏中被淘汰');
    }
    return queue.dequeue();
}

var names = ['John', 'Jack', 'Camila', 'Ingrid', 'Carl'];
var winner = hotPotato(names, 7);
console.log('胜利者:' + winner);

以上小游戏的输出如下:

Camila在击鼓传花游戏中被淘汰
Jack在击鼓传花游戏中被淘汰
Carl在击鼓传花游戏中被淘汰
Ingrid在击鼓传花游戏中被淘汰
胜利者:John

1人推荐
随时随地看视频
慕课网APP