javascript資料結構 -- 棧

Vadim發表於2019-06-21

學習資料結構非常重要。首要原因是資料結構和演算法可以很高效的解決常見問題。作為前端,通過javascript學習資料結構和演算法要比學習java和c版本容易的多。

在講資料結構之前我們先了解一下ES6的一些方法。因為這可能對我們瞭解資料結構有幫助。

ES6運算元組的方法

首先我們來用箭頭函式定義一個函式。

const isEven = x => x % 2 === 0;
let numbers = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];

  

1.event方法迭代

此方法會迭代陣列中每個元素,如果每個元素都返回true,此方法才會返回true.

numbers.every(isEven);

因為並不是每個數字都是偶數。所以返回false;

2.some方法迭代

此方法會迭代陣列中每個元素,如果有元素都返回true,此方法才會返回true.

numbers.some(isEven);

因為有偶數元素,所以返回true;

3.forEach方法迭代

此方法會迭代陣列中的每個元素,然後分別執行傳入的回到函式。

number.forEach(callback);

4.map方法迭代

此方法會將陣列的每個元素通過回撥函式,並將每個返回值組成新的陣列返回。

numbers.map(isEven);

返回[false,true,false,true,false,true,false,true,false,true,false,true,false,true,false];

5.filter方法迭代

此方法返回的新陣列由使回撥函式返回true的元素組成。

numbers.filter(isEven);

因為2,4,6,8,10,12,14模2等於0;所以返回[2,4,6,8,10,12,14];

6.reduce方法迭代

此方法有四個引數previousValue,currentValue,index,array.後連個引數為可選引數,可以不傳。這個函式會返回一個將被疊加到疊加器的值。

numbers.reduce((previous, current) => previous + current)

我們來分解一下reduce執行過程。第一個previous為1,current為2 return為1+2=3。在第二次迭代中previous為上一個迭代的返回值3,current為3, return為6 …因此最後返回120。

除此之外,ES6還新增了很多語法糖。有興趣的同學可以去阮大神的個人部落格。

1.什麼是棧?

基礎的東西簡單的介紹完了,接下來我們來點乾貨。那麼什麼是棧呢?棧是一種遵從後進先出(LIFO)原則的有序集合。新新增和待刪除的元素都儲存在棧的同一端,稱作棧頂,另一端就叫棧底。在棧裡,新元素都靠近棧頂,舊元素都接近棧底。就像生活中廚房裡疊放的盤子。

2.建立基於JavaScript陣列的棧

先從宣告一個Stack類開始。

class Stack {
  constructor() {
    this.items = [];
  }
}

接下來我們新增一些方法。

  • 1.push(element);新增元素到棧頂
  • 2.pop();移除棧頂元素,並返回移除元素
  • 3.peek();返回棧頂的元素
  • 4.isEmpty();如果站裡沒有元素則按返回true,反之返回false
  • 5.clear();移除棧裡所有元素
  • 6.size();返回棧裡元素個數

push方法

push(element) {
  this.items.push(element);
}

pop方法

pop() {
  return this.items.pop();
}

peek方法

peek() {
  return this.items[this.items.length - 1];
}

isEmpty方法

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

  

clear方法

clear() {
  this.items = [];
}

size方法

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

3.建立基於JavaScript物件的棧

先從宣告一個Stack類開始。

class Stack {
  constructor() {
    this.count = 0;
    this.items = {};
  }
}

接下來我們新增一些方法。

  • 1.push(element);新增元素到棧頂
  • 2.pop();移除棧頂元素,並返回移除元素
  • 3.peek();返回棧頂的元素
  • 4.isEmpty();如果站裡沒有元素則按返回true,反之返回false
  • 5.clear();移除棧裡所有元素
  • 6.size();返回棧裡元素個數

push方法

push(element) {
  this.items[this.count] = element;
  this.count ++;
}

pop方法

pop() {
  if(this.isEmpty()) {
    return undefined;
  }
  this.count --;
  let result = this.items[this.count];
  delete this.items[this.count]
  return result;
}

peek方法

peek() {
  if(this.isEmpty()) {
    return undefined;
  }
  return this.items[this.count - 1];
}

isEmpty方法

isEmpty() {
  return this.count == 0;
}

clear方法

clear() {
  this.count = 0;
  this.items = {};
}

size方法

size() {
  return this.items.count;
}

toString方法

因為陣列版本的棧的toString()方法可以直接使用陣列提供的toString方法,為物件版則需要我們自己封裝。

toString() {
  if(this.isEmpty()) {
    return ''
  }
  let objString = `${this.items[0]}`;
  for(let i=1; i<this.count; i++) {
    objString = `${objString},${this.items[i]}`
  }
  return objString;
}

這就是我們用javascript版本的棧資料結構。

4.用棧解決問題

下面我們以10進位制轉2進製為例,看看如何用棧決絕問題。

function decimalToBinary(decNumber) {
  const remStack = new Stack();
  let number = decNumber;
  let rem;
  let binaryString = '';
  while(number > 0) {
    rem = Math.floor(number % 2);
    remStack.push(rem);
    number = Math.floor(number / 2);
  }
  if(!remStack.isEmpty()) {
    binaryString += this.pop().toString();
  }
  return binaryString;
}

這便是用資料結構解決問題。後續我會將用JavaScript講解什麼是佇列、連結串列、集合、字典、雜湊表(HashTable)、遞迴、樹、二叉堆、圖等資料結構。

 

原創部落格:轉載請註明:javascript資料結構 – 棧

相關文章