一、棧:後入先出()
1.棧結構實現:
function Stack() {
var items = []; // 使用私有變量,避免被外部操作
// push 棧頂添加元素
this.push = function(ele) {
items.push(ele);
}
// pop 移除棧頂元素 需返回移除的元素 因爲可能要用到
this.pop = function() {
return items.pop();
}
// peek 檢查棧頂
this.peek = function() {
return items[items.length - 1];
}
// isEmpty 檢查棧是否爲空
this.isEmpty = function() {
return items.length == 0;
}
// clear 清除棧
this.clear = function() {
items = [];
}
// size 獲取棧大小
this.size = function() {
return items.length;
}
// getItems 檢查items
this.getItems = function() {
return items;
}
}
// 使用棧
var stack = new Stack();
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.getItems());
// stack.pop(); // 使用pop會使整個數組改變,上方的打印也會受影響
console.log(stack.peek());
console.log(stack.isEmpty());
console.log(stack.size());
stack.clear()
console.log(stack.getItems());
2.使用案例:十進制轉二進制
思路:使用餘數法 ,將所有餘數依次放入棧中,棧頂爲最後剩餘的數,最後依次pop棧中的數據並整理成字符串。
實現:
方法一:使用while
// 十進制轉二進制
var divBy2 = function(number) {
var stack = new Stack();
var remainder;
var str = '';
while(number > 0) {
remainder = number % 2;
stack.push(remainder);
number = Math.floor(number / 2);
}
while(!stack.isEmpty()) {
str += stack.pop();
}
return str;
}
console.log(divBy2(10));
方法二:使用遞歸
var divBy2 = function(number) {
var stack = new Stack();
// 獲取
return loop(stack,number)
}
// 遞歸
function loop(stack,newNum) {
// 獲取商
var quotient = Math.floor(newNum / 2);
// 獲取餘數
var remainder = newNum % 2;
// 將餘數放入棧中
stack.push(remainder);
// 將商進行遞歸
if(quotient < 2) {
stack.push(quotient);
return stack.getItems();
} else {
loop(stack,quotient)
}
return stack.getItems();
}
console.log(divBy2(10));
3.內存中的棧和函數:
二、隊列()
1.隊列結構實現:
var Queue = function() {
var items = [];
// enqueue 入列
this.enqueue = function(ele) {
items.push(ele)
}
// dequeue 出列
this.dequeue = function() {
return items.shift();
}
// front 查看列頭
this.front = function() {
return items[0]
}
// isEmpty 檢查隊列是否爲空
this.isEmpty = function() {
return items.length == 0;
}
// size 檢查隊列大小
this.size = function() {
return items.length;
}
}
2.使用案例:傳花遊戲
思路:一羣小夥伴坐一圈傳遞一朵花,自定義第n位被淘汰,如此循環至剩下一個人 。
實現:
// 傳花遊戲:一羣小夥伴坐一圈傳遞一朵花,自定義第n位被淘汰,如此循環至剩下一個人 。
var chuanhua = function(names,num) {
var queue = new Queue();
// 將所有小夥伴放入隊列中
for(var i = 0; i < names.length; i++) {
queue.enqueue(names[i]);
}
while(queue.size() > 1) {
// 隊列中的前n-1個小夥伴插入到列尾
for(var i = 0; i < num - 1; i++) {
queue.enqueue(queue.dequeue());
}
// 第n個小夥伴出列
taotai = queue.dequeue()
}
// 返回最後一個小夥伴
return queue.dequeue()
}
var names = ['a','b','c','d','e','f'];
var num = 3;
console.log(chuanhua(names,num));
3.優先隊列:設置優先級,數字大的排前
// 優先隊列
var PriorityQueue = function() {
var items = [];
// 輔助類:因爲優先隊列需要制定優先級,所以隊列中的項應該是對象{ele:ele,priority:priority}
function QueueItem(ele, priority) {
this.ele = ele;
this.priority = priority;
}
// enqueue 優先隊列的入隊方法
this.enqueue = function(ele,priority) {
var queueItem = new QueueItem(ele,priority);
var status = false;
for(var i = 0; i < items.length; i ++) {
if(queueItem.priority > items[i].priority) {
items.splice(i,0,queueItem);
status = true;
// 中斷循環,避免ele被插入之後繼續向後找位置插入
break;
}
}
if(status == false) {
items.push(queueItem);
}
return items;
}
this.getItem = function() {
return items;
}
}
var priorityQueue = new PriorityQueue();
priorityQueue.enqueue('小明',1)
priorityQueue.enqueue('小黃',8)
priorityQueue.enqueue('小紅',6)
priorityQueue.enqueue('小黑',4)
console.log(priorityQueue.getItem());