数据结构—队列、堆栈

数据结构-队列、堆栈

堆栈和队列是特殊的线性表。数据元素的逻辑关系完全相同。

队列

FIFO - 先进先出:
只允许在一端进行插入操作,称为队头;另一端进行删除操作,称为队尾;

需要实现的方法:

  1. 队列初始化大小:init,接受参数size;
  2. 是否为空isEmpty:非空返回false,为空返回true;
  3. 添加元素append,接受一个参数value;操作成功返回true,失败则返回false
  4. 删除元素delete,操作成功返回true,失败则返回false
顺序队列

按顺序存储的队列。需要解决存在的一个问题假溢出
如图,顺序队列的操作:
在这里插入图片描述
从图中可以看出队列的操作:队头删除、队尾添加;
假溢出即队列中还存在位置 但是没法使用,造成浪费;需要解决。
真溢出即队列只添加元素,不删除,则不存在空闲。

循环队列

为了解决顺序队列的假溢出

循环队列即队头、队尾相连,当前队尾rear值达到最大size时,值取 0

需要解决的两个问题:队列空、队列满

  1. 少用一个存储单元;
    // 队列满
    (rear+1)%size == front
    // 队列空
    rear == front
    
  2. 设置标志位tag,进队列为1 ,出队列为 0;
    // 队列空
    rear == front && tag==0
    // 队列满
    rear == front && tag ==1
    
  3. 设置计数器count,进队列+1,出队列-1;
    // 队列空
    count == 0
    // 队列满
    count>0 && rear == front
    

程序代码的实现:
采用第三种方式解决队列满、队列空的问题;

function quene(size){
	// 初始化队列大小
    this.size = size;
    // 初始化一个固定大小的数组,存储数据
    this.arr = new Array(this.size);
    // 队头
    this.front = 0;
    // 队尾
    this.rear = 0;
    // 计数器,解决队列满和队列空的问题
    this.count = 0;
}
quene.prototype = {
	// 添加元素
    append:function(value){
        debugger;
        // 队列满时返回false,
        if(this.isFull()){
            return false;
        }
        // 存储值,队尾指针后移一位
        this.arr[this.rear] = value;
        // 处理当队尾值大于队列等于队列大小时 =0;
        this.rear = (this.rear+1) % this.size;
        // 计数 ,+1
        this.count++;
        return true;
    },
    // 删除,队列从队头删除
    delete:function(){
    	// 为空时返回false
        if(this.isEmpty()){
            return false;
        }
        // 出队列的值可用作它用,在此赋值为null;
        this.arr[this.front] = null;
        // 处理队头指针移位
        this.front = (this.front+1) % this.size;
        // 计数 , -1
        this.count--;
        return true;
    },
    // 取队头值
    frontValue:function(){
    	// 队列空时 返回  -1
	    if(this.isEmpty()){
	      	return -1;
	    }
        return this.arr[this.front];
    },
    // 取队尾值
    rearValue:function(){
    	if(this.isEmpty()){
	       return -1;
	    }
	    // 队列非空时,且队尾指针为 0 ;数组取不到负数值,则为数组最后一个值。
	    if(this.end == 0){
	       return this.arr[this.end-1+this.size]
	    }
        return this.arr[this.rear-1];
    }
    isEmpty:function(){
    	// 计数器为 0 则队列为空
        if(this.count == 0){
            return true;
        }
        return false;
    },
    // 队列是否已满
    isFull:function(){
        if(this.count>0 && this.front == this.rear){
            return true;
        }
        return false;
    }
}

接上一个图:
循环利用闲置的队列单元。解决假溢出的问题;
在这里插入图片描述

链式队列
堆栈

LIFO - 后进先出

在栈顶进行数据的插入和删除。(记得之前学过的一篇文章,詹天佑的双向火车头字形铁路)

数据操作集合:

  1. 初始化init
  2. 非空判断isEmpty;为空返回 true ,否返回false
  3. 入栈push;
  4. 出栈pop;
  5. 取栈顶元素top;

代码实现,JS中提供的数组操作方法很简单就实现堆栈。

var MinStack = function(size) {
    this.arr = new Array();
    // 栈初始化大小
    this.size = size;
    // 栈顶元素下标
    this.topIndex = 0;
};

/** 
 * @param {number} x
 * @return {void}
 */
MinStack.prototype.push = function(x) {
    if(this.isFull()){
        console.warn("栈已满无法插入!");
        return false;
    }
    this.arr.push(x);
    this.topIndex++;
};

/**
 * @return {void}
 */
MinStack.prototype.pop = function() {
    if(this.isEmpty()){
        console.warn("栈已空无数据出栈!");
        return false;
    }
    this.arr.pop();
    this.topIndex--;
};

/**
 * @return {number}
 */
MinStack.prototype.top = function() {
    return this.arr[this.topIndex - 1];
};

/**
 * @return {number}
 */
MinStack.prototype.getMin = function() {
    let result = this.arr[0];
    for(let i=1,len = this.arr.length;i<len;i++){
        if(result>this.arr[i]){
           result = this.arr[i];
        }
    }
    return result;
};
/**
 * 是否为空
 */
MinStack.prototype.isEmpty = function(){
    return this.topIndex == 0;
}
/**
 * 是否已满
 */
MinStack.prototype.isFull = function(){
    return this.topIndex == this.size;
}

栈相对现有 数组 的方法比较简单,也好理解。

链式堆栈
优先级探讨
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

heroboyluck

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值