最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

每周一練 之 數(shù)據(jù)結構與算法(Stack)

 更新時間:2019年04月16日 09:59:49   作者:pingan8787  
這篇文章主要介紹了數(shù)據(jù)結構與算法(Stack),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

最近公司內(nèi)部在開始做前端技術的技術分享,每周一個主題的 每周一練,以基礎知識為主,感覺挺棒的,跟著團隊的大佬們學習和復習一些知識,新人也可以多學習一些知識,也把團隊內(nèi)部學習氛圍營造起來。

我接下來會開始把每周一練的題目和知識整理一下,便于思考和鞏固,就像今天這篇開始。

學習的道路,很漫長,要堅持,希望大家都能掌握自己喜歡的技術,和自己需要的技術。

本周練習內(nèi)容:數(shù)據(jù)結構與算法 —— Stack

這些都是數(shù)據(jù)結構與算法,一部分方法是團隊其他成員實現(xiàn)的,一部分我自己做的,有什么其他實現(xiàn)方法或錯誤,歡迎各位大佬指點,感謝。

一、棧有什么特點,生活中有什么例子?

  1. 棧( stack )又稱堆棧,是一種后進先出的有序集合,其中一端為棧頂,另一端為棧底,添加元素(稱為壓棧/入?;蜻M棧)時,將新元素壓入棧頂,刪除元素(稱為出?;蛲藯#r,將棧底元素刪除并返回被刪除元素。
  2. 特點:先進后出,后進先出。
  3. 例子:一疊書、一疊盤子。

 

二、實現(xiàn)一個棧,并實現(xiàn)下面方法

  1. push(element):添加一個新元素到棧頂。
  2. pop():移除棧頂?shù)脑?,同時返回被移除的元素。
  3. peek():返回棧頂?shù)脑?,不對棧做任何修?(這個方法不會移除棧頂?shù)脑兀瑑H僅返回它)。
  4. isEmpty():如果棧沒有任何元素就返回 true,否則返回 false。
  5. clear():移除棧里面的所有元素。
  6. size():返回棧里的元素個數(shù)。這個方法與數(shù)組的 length 屬性類似。

方法1:ES6實現(xiàn)

class Stack {
  constructor (){
    this.items = []
  }
  push( element ){
    this.items.push(element)
  }
  pop(){
    return this.items.pop()
  }
  peek(){
    return this.items[this.items.length - 1]
  }
  isEmpty(){
    return this.items.length === 0
  }
  clear(){
    this.items = []
  }
  size(){
    return this.items.length
  }
}

上面實現(xiàn)的方式雖然簡單,但是內(nèi)部 items 屬性是公共的,為了滿足面向?qū)ο笞兂伤接行缘脑瓌t,我們應該讓 items 作為私有屬性,因此我們可以使用 ES6 中 Symbol 或 WeakMap 來實現(xiàn):

方法2:使用 ES6 的 Symbol 基本數(shù)據(jù)類型實現(xiàn)
知識點復習:ES6 中的 Symbol 介紹

const _items = Symbol()
class Stack {
  constructor (){
    this[_items] = []
  }
  push (element){
    this[_items].push(element)
  }
  // 剩下方法和第一種實現(xiàn)的差不多,這里省略
  // 只要把前面方法中的 this.items 更改為 this[_items]
}

 方法3:使用 ES6 的 WeakMap 實現(xiàn)

知識點復習:ES6 中的 WeakMap 介紹

 

const items = new WeakMap()
class Stack {
  constructor (){
    items.set(this, [])
  }
  push (element){
    let item = items.get(this)
    item.push(element)
  }
  // 剩下方法和第一種實現(xiàn)的差不多,這里省略
  // 只要把前面方法中的獲取 this.items 的方式,更改為 items.get(this) 獲取
}

 三、編寫一個函數(shù),實現(xiàn)十進制轉(zhuǎn)二進制

題目意思很簡單,就是十進制轉(zhuǎn)二進制,但是在實際工作開發(fā)中,我們更愿意實現(xiàn)的是任意進制轉(zhuǎn)任意進制,不過呢,我們還是以解決問題為首要目標呀。

當然,業(yè)務需求可以直接使用 toString(2) 方法,但是為了練習,咱還是不這么用咯。

方法1:使用前面定義的 Stack 類

這里使用前面題目中定義的 Stack 類。

/**
 * 十進制轉(zhuǎn)換為二進制
 * @param {Number} bit 
 */
function bitset (bit){
  if(bit == 0) return '0'
  if(!/^[0-9]+.?[0-9]*$/.test(bit)){
    return new Error('請輸入正確的數(shù)值!')
  }

  let stack = new Stack(), result = ''
  while (bit > 0){
    stack.push(bit % 2)
    bit = Math.floor(bit / 2)
  }
  while (!stack.isEmpty()){
    result += stack.pop().toString()
  }
  return result

}

方法2:簡單實現(xiàn)

下面這個方法,其實不太好,因為沒有怎么用到這次要練習的棧方法,哈哈。

/**
 * 十進制轉(zhuǎn)換為二進制
 * @param {Number} bit 
 */
function bitset (bit){
  if(bit == 0) return '0'
  if(!/^[0-9]+.?[0-9]*$/.test(bit)){
    return new Error('請輸入正確的數(shù)值!')
  }

  let arr = []
  while(bit > 0){
    arr.push(bit % 2)
    bit = Math.floor(bit / 2)
  }
  return arr.reverse().join('')
}

另外可以參考:wikiHow - 從十進制轉(zhuǎn)換為二進制。

四、編寫一個函數(shù),實現(xiàn)檢驗圓括號順序的有效性

主要目的就是:該函數(shù)接收一個圓括號字符串,判斷里面的括號順序是否有效,如果有效則返回 true 反之 false。
如:

  1. (   -> false
  2. ()  -> true
  3. (() -> false
  4. ()) -> false
  5. ()) -> false
  6. (((()()))()) -> true

這個題目實現(xiàn)的主要方法是:遍歷字符串,先排除錯誤情況,然后將 ( 入棧保存,將 ) 入棧匹配前一個元素是否是 ( ,如果是,則 pop() 前一個元素 (,如果不是,則 push() 這個 ) 入棧,最終查看棧是否為空,若是則檢驗成功,否則失敗。

方法1:使用前面定義的 Stack 類

這里使用前面題目中定義的 Stack 類。

/**
 * 檢驗圓括號順序的有效性
 * @param {String} str 
 */
function validParentheses (str){
  if(!str || str.length === 0 || str[0] === ')') return false

  let stack = new Stack()
  str.split('').forEach(char => {
    let status = stack.peek() === '(' && char === ')'
    status ? stack.pop() : stack.push(char)
  })
  return stack.isEmpty()
}

方法2:出入棧操作

/**
 * 檢驗圓括號順序的有效性
 * @param {String} str 
 */
function validParentheses (str){
  if(!str || str.length === 0 || str[0] === ')') return false

  let arr = []
  for(let i = 0; i < str.length ; i++){
    str[i] === '(' ? arr.push(str[i]) : arr.pop()
  }
  return arr.length === 0
}

五、改造題二,添加一個 min 函數(shù)來獲得棧中最小元素

步驟 數(shù)據(jù)棧 輔助棧 最小值
1.push 3 3 0 3
2.push 4 3, 4 0, 0 3
3.push 2 3, 4, 2 0, 0, 2 2
4.push 1 3, 4, 2 ,1 0, 0, 2, 3 1
5.pop 3, 4, 2 0, 0, 2 2
6.pop 3, 4 0, 0 3
7.push 3, 4 ,0 0, 0, 2 0

使用示例如下:

let stack = new Stack();
stack.push(3);
console.log('After push 3, Min item is', stack.min());
stack.push(4);
console.log('After push 4, Min item is', stack.min());
stack.push(2);
console.log('After push 2, Min item is', stack.min());
stack.push(1);
console.log('After push 1, Min item is', stack.min());
stack.pop();
console.log('After pop, Min item is', stack.min());
stack.pop();
console.log('After pop, Min item is', stack.min());
stack.push(0);
console.log('After push 0, Min item is', stack.min());

提示:利用輔助棧(Web 端可利用數(shù)組),每次對棧 push/pop 元素時,也同時更新輔助棧(存儲最小元素的位置)

方法1:小操作

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

 push(element) {
  this.items.push(element);
  let minLen = this.minIndexStack.length;
  let minItemIndex = this.minIndexStack[minLen - 1];
  if(minLen === 0 || this.items[minItemIndex] > item) {
   this.minIndexStack.push(this.items.length - 1);
  } else {
   this.minIndexStack.push(minItemIndex);
  }
 }

 pop() {
  this.minIndexStack.pop();
  return this.items.pop();
 }
 
 min() {
  let len = this.minIndexStack.length;
  return (len > 0 && this.items[this.minIndexStack[len - 1]]) || 0;
 }

 peek() {
  return this.items[this.items.length - 1];
 }
 
 // 省略其它方法
}

方法2:與方法1中push實現(xiàn)的差異

class Stack {
  constructor (){
    this.items = [] // 數(shù)據(jù)棧
    this.arr = []  // 輔助棧
  }
  push( element ){
    this.items.push(element)
    let min = Math.min(...this.items)
    this.arr.push( min === element ? this.size() - 1 : 0)
  }
  pop(){
    this.arr.pop()
    return this.items.pop()
  }
  peek(){
    return this.items[this.items.length - 1]
  }
  isEmpty(){
    return this.items.length === 1
  }
  clear(){
    this.items = []
  }
  size(){
    return this.items.length
  }
  min (){
    let last = this.arr[this.arr.length - 1]
    return this.items[last]
  }
}

以上所述是小編給大家介紹的數(shù)據(jù)結構與算法(Stack)詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!

相關文章

  • 微信小程序虛擬列表的應用實例

    微信小程序虛擬列表的應用實例

    虛擬列表不是什么神秘的東西,下面這篇文章主要給大家介紹了關于微信小程序虛擬列表的應用實例,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-12-12
  • javascript高亮效果的二種實現(xiàn)方法

    javascript高亮效果的二種實現(xiàn)方法

    js高亮效果實現(xiàn)代碼,直接靜態(tài)頁面即可,不用每次都要生成
    2008-09-09
  • 跟我學習javascript的隱式強制轉(zhuǎn)換

    跟我學習javascript的隱式強制轉(zhuǎn)換

    跟我學習javascript的隱式強制轉(zhuǎn)換,感興趣的小伙伴們可以學習一下
    2015-11-11
  • js幾秒以后倒計時跳轉(zhuǎn)示例

    js幾秒以后倒計時跳轉(zhuǎn)示例

    使用js實現(xiàn)幾秒以后倒計時跳轉(zhuǎn),這個在某些特殊情況下還是比較實用的,下面為大家介紹下具體的實現(xiàn)步驟,感興趣的朋友不要錯過
    2013-12-12
  • js實現(xiàn)上傳圖片之上傳前預覽圖片

    js實現(xiàn)上傳圖片之上傳前預覽圖片

    此功能用js實現(xiàn),然后在fileupload控件的change事件中調(diào)用,這樣當用fileupload選擇完圖片以后,圖片就會自動顯示出來了,感興趣的各位可以參考下哈
    2013-03-03
  • JavaScript運動框架 解決速度正負取整問題(一)

    JavaScript運動框架 解決速度正負取整問題(一)

    這篇文章主要為大家詳細介紹了JavaScript運動框架的第一部分,解決速度正負取整問題,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • JavaScript html5 canvas繪制時鐘效果

    JavaScript html5 canvas繪制時鐘效果

    這篇文章主要介紹了JavaScript html5繪制時鐘效果的相關資料,使用HTML5的canvas標簽和Javascript腳本,模擬顯示了一個時鐘,感興趣的小伙伴們可以參考一下
    2016-03-03
  • 原生js實現(xiàn)圖片放大縮小計時器效果

    原生js實現(xiàn)圖片放大縮小計時器效果

    本文主要介紹了原生js實現(xiàn)圖片放大縮小計時器效果的示例代碼。具有一定的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • 詳解RequireJS按需加載樣式文件

    詳解RequireJS按需加載樣式文件

    本篇文章主要介紹了RequireJS按需加載樣式文件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • JS Array對象入門分析

    JS Array對象入門分析

    每天一對象,今天我們也來new一個。沒有系統(tǒng)的學過JS,沒有特別的寫過一個比較出色的類庫,沒有運用過一個很強的類庫,prototype.js在進行著,慢慢的前進相信不久的將來就可以應用prototype.js來開發(fā)自己的應用程序了。
    2008-10-10

最新評論

宜城市| 吉隆县| 鱼台县| 武强县| 乾安县| 定襄县| 建水县| 色达县| 泰顺县| 门源| 南皮县| 宜宾市| 凌海市| 田东县| 中卫市| 上蔡县| 姚安县| 阜新市| 栾川县| 陆河县| 凤冈县| 木里| 德化县| 疏勒县| 包头市| 绥棱县| 闻喜县| 太原市| 奉化市| 邹城市| 临桂县| 阜阳市| 新安县| 晋江市| 黎城县| 同德县| 阆中市| 江北区| 庆云县| 陈巴尔虎旗| 临泽县|