数据结构-队列、堆栈
堆栈和队列是特殊的线性表。数据元素的逻辑关系完全相同。
队列
FIFO
- 先进先出:
只允许在一端进行插入操作,称为队头;另一端进行删除操作,称为队尾;
需要实现的方法:
- 队列初始化大小:
init
,接受参数size
; - 是否为空
isEmpty
:非空返回false
,为空返回true
; - 添加元素
append
,接受一个参数value
;操作成功返回true
,失败则返回false
- 删除元素
delete
,操作成功返回true
,失败则返回false
顺序队列
按顺序存储的队列。需要解决存在的一个问题假溢出
如图,顺序队列的操作:
从图中可以看出队列的操作:队头删除、队尾添加;
假溢出
即队列中还存在位置 但是没法使用,造成浪费;需要解决。
真溢出
即队列只添加元素,不删除,则不存在空闲。
循环队列
为了解决顺序队列的假溢出
。
循环队列即队头、队尾相连,当前队尾rear值达到最大size时,值取 0
;
需要解决的两个问题:队列空、队列满
- 少用一个存储单元;
// 队列满 (rear+1)%size == front // 队列空 rear == front
- 设置标志位
tag
,进队列为1 ,出队列为 0;// 队列空 rear == front && tag==0 // 队列满 rear == front && tag ==1
- 设置计数器
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
- 后进先出
在栈顶进行数据的插入和删除。(记得之前学过的一篇文章,詹天佑的双向火车头人
字形铁路)
数据操作集合:
- 初始化
init
- 非空判断
isEmpty
;为空返回true
,否返回false
- 入栈
push
; - 出栈
pop
; - 取栈顶元素
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;
}
栈相对现有 数组 的方法比较简单,也好理解。