一、栈
先进后出,后进先出,栈满无法进栈,栈空无法再进行提取
1、封装一个栈:
** class stack{
constructor(){
// 返回数组对象原型的函数
this.item=[]; //我在这里设定栈的大小
//这边设置栈的长度
this.items =[3];
}
push(el){
//向栈顶添加元素
//因为栈的先进后出,而且它添加的方式都是从栈顶开始
this.item.push(el);
//这边模仿一个栈满的情况
if(this.items.length !=3){
this.items.push(el)
}else if(this.items.length =3){
console.log("栈满,停止进栈",this.item);
}
}
pop(){
//pop删除最后一个元素
// 相当于出栈
return this.item.pop();
}
size(){
// 获取栈的元素个数
return this.item.length;
}
toString(){
// 将元素转字符串类型
return this.item.join('-');
}
isEmpty(){
// 判断栈是否为空
return this.item.length === 0;
}
find(){
return this.item[this.item.length - 1];
}
}
let zhan = new stack();
zhan.push('crt'); //0
zhan.push('boy'); //1
zhan.push('18'); //2
// zhan.push('man'); 因为我在上方设置了栈的长度,所以超过这个长度就无法存储
console.log(zhan);
console.log(zhan.pop(),zhan); //删除栈
console.log(zhan.size()); // 2 0,1,2
console.log(zhan.find()); // crt
console.log(zhan.toString());**
2、栈的应用
//利用栈实现一个十进制转二进制的函数
// 十进制转二进 就是 用2除去十进制数,然后然后得到商和余数记录下来 然后新商再除以二 直到商为0
// 每次把求出来余 放入栈中,然后再把它提取出来进行计算
function getNumber(decimalNumber){
let foot = new stack();
// 创建一个实例对象
while(decimalNumber > 0){
foot.push(decimalNumber % 2); //这边将余数存放在 栈中
decimalNumber = Math.floor(decimalNumber / 2); // 这2条相当于就是执行了十进二的操作
}
let result = '';
while(!foot.isEmpty()){ //这边判断它如果不是为空那就将它放在result这个容器中
result += foot.pop();
}
return result;
}
console.log(getNumber(100)); //1100100
console.log(getNumber(26)); // 11010
二、队列的应用
封装一个队列
class King{
constructor() {
this.items = [];
}
add(el) {
this.items.push(el);
}
delet() {
return this.items.shift();
// shift 是删除头部
// pop 跟它相反 是删除尾部
}
front() {
return this.items[0];
}
size() {
return this.items.length;
}
}
let ququ = new King();
ququ.add("red");
ququ.add("blue");
ququ.add("green");
console.log(ququ.delet(),ququ);
队列的应用
**队列应用击鼓传花
击鼓传花规则:
围成一圈数数,比如规定数到5的人淘汰,
那么淘汰的人后面的人从1开始数,然后数到5的人再淘汰,
以此类推,直到剩下最后一个人,求该人的位置
思路:围成一圈的话,可以看成一个队列,从第一个人开始数,
那么在数到`num`之前的人可以依次从队头删除,加入队尾(保持环形结构)。
直到被数到的这个人到队头,然后把它删除就行了。**
let queue = new King();
//定义一个列队,然后将数据依次加入队列
for(let i = 0; i < nameList.length; i++) {
queue.add(nameList[i]);
}
console.log('初始队列元素:',queue.items);
//从第一个人开始数
while(queue.size() > 1) {
for(let i = 0; i < num - 1; i++) {
queue.add(queue.delet());
}
// 主要点:从列头部删除的元素,然后将删除的元素添加到列尾部
queue.delet();
console.log(`人数变化:`,queue.items);
}
//4.把剩下那个人的名字和位置找出来
let leftBoy = queue.front();
let index = nameList.indexOf(leftBoy);
console.log(`剩下的哥们儿是${leftBoy},他的初始位置是:${index}`);
return index;
}
passGame(['张三','李四','王五','赵六','田七','郭八'], 5);
3、封装优先队列
封装队列:
1、这个是什么东西
就是有人可以进行一个插队,封装的时候要带上一个标识符,所以标识的元素可以进行插队/往前靠,
所以说明这需要两个参数。`element(元素)`和`priority(优先级标识)`
2、封装逻辑:
先声明一个内部元素类,用来存储(元素,优先级)两个属性
封装优先队列,通过继承父类的属性和方法(使用super关键字去调用父类方法)
重写插入方法
重写的逻辑:
(1)首先判断是否为空,空就直接队尾插入;
(2)不为空,就要遍历当前队列元素,插入的新值依次比较,如果新值优先级较低,那么就使用splice插入到当前 位置的前面(把其他的顶到后面),同时跳出循环。
(3)如果比较完之后新插入元素优先级最高,那么直接插入到队尾。
class QueueElement {
constructor(element, priority) {
this.element = element;
this.priority = priority;
}
}
//封装优先级队列
class PriorityQueue extends King {
constructor() {
super(); //super关键字调用父类的构造函数
}
//重写add方法
add(element, priority) {
//1.根据传入的元素,创建一个元素对象实例
let queueElement = new QueueElement(element, priority);
//2.1判断队列是否为空,如果为空那么直接push进去
if (this.isEmpty()) {
this.items.push(queueElement);
} else {
//2.2如果不为空,那么比较优先级(这里默认小的优先)
let added = false; //定义一个标识,判断是否已经插入
for (let i = 0; i < this.items.length; i++) {
//3.如果插入的元素优先级更小,那么就在当前位置插入(其他的被挤到后面)
if (queueElement.priority < this.items[i].priority) {
this.items.splice(i, 0, queueElement);
//splice的用法:splice(位置,删除几个,替换的元素)
added = true; //插入完成,修改标识
break; //如果插入完成,就跳出循环
}
}
//4.如果遍历结束后,新元素始终最大,那么就添加到队尾
if(!added) {
this.items.push(queueElement);
}
}
}
//其他方法全部继承(转字符串需要小改)
delte() {
return super.delte(); //super关键字调用父类的函数
}
front() {
return super.front();
}
isEmpty() {
return super.isEmpty();
}
size() {
return super.size();
}
toString() {
let result = "";
for(let item of this.items) {
result += `${item.element}-${item.priority} `;
}
return result;
}
}
//测试代码
const queue = new PriorityQueue();
queue.add('zzy',10); //参数1为元素,参数2为优先级
queue.add('nba',50);
queue.add('cba',20);
queue.add('dj',40);
queue.add('ht',30);
console.log(queue.items);
console.log(queue.toString()); //zzy-10 cba-20 ht-30 dj-40 nba-50