Javascript資料結構與演算法--棧的實現與用法
棧資料結構
棧是一種遵從後進先出(LIFO)原則的有序集合。新新增的或者待刪除的元素都儲存在棧的同一端,稱作棧頂,另一端就叫棧底。在棧裡,新元素都靠近棧頂,舊元素都接近棧底。
我們在生活中常能看到棧的例子。整齊堆起來的書,廚房堆起的盤子等
棧也被用在程式語言的編譯器和記憶體中儲存變數、方法呼叫等。
/** * 使用es6中的Class語法來編寫類:棧 * 此棧使用陣列來儲存元素 */ class Stack { constructor() { this.items = []; } /** * 新增一個(或幾個)新元素到棧頂 * @param {*} element 新元素 */ push(element) { this.items.push(element) } /** * 移除棧頂的元素,同時返回被移除的元素 */ pop() { return this.items.pop() } /** * 返回棧頂的元素,不對棧做任何修改(這個方法不會移除棧頂的元素,僅僅返回它) */ peek() { return this.items[this.items.length - 1] } /** * 如果棧裡沒有任何元素就返回true,否則返回false */ isEmpty() { return this.items.length === 0 } /** * 移除棧裡的所有元素 */ clear() { this.items = [] } /** * 返回棧裡的元素個數。這個方法和陣列的length屬性很類似 */ size() { return this.items.length } /** * 返回以字串形式輸出的棧 */ toString() { return this.items.toString() } /** * 返回以陣列形式輸出的棧 */ toArray() { return this.items } }
棧的用法
進位制轉換
更多詳情請檢視原始碼
在計算機裡所有的內容都是二進位制數字表示的(0和1),而我們生活中主要用到十進位制,還有16進位制等。那麼就需要進位制轉換。我們可以利用棧來實現轉換。
/** * 10進位制數轉換為其他16進位制以內進位制的數 * @param {*} decNumber 需要轉換的數 * @param {Int32Array} hex 進位制數 */ function hexConverter(decNumber, hex) { let remStack = new Stack() let rem = 0 let baseString = '' let digits = '0123456789ABCDEF' //進製取數 if (hex < 2 || hex > 16) { return '只轉換大於二進位制小於十六進位制之間的進位制' } while (decNumber > 0) { rem = Math.floor(decNumber % hex) // 求模運算 remStack.push(rem) decNumber = Math.floor(decNumber / hex) // 除運算 } while (!remStack.isEmpty()) { baseString += digits[remStack.pop()] // 取出棧中的資料對應於進位制數的表示數 } return baseString }
迴文判斷
更多詳情請檢視原始碼
正讀反讀都相同的字元序列稱為迴文,例如“abccba”、“abcba”、“12321”、“123321”。
迴文判斷有很多種方法,在這裡,我們可以採用先入棧後出棧的方法,來比較入棧之前,和出棧之後兩個字串是否相同。
空字串到底是不是迴文呢,有點疑惑? 我這裡定義為不是迴文。
/** * 判斷字串是否為迴文 * @param {String} str 要判斷的字串 */ function palindrome(str) { // 非string型別的 或者 空字串 直接判斷不是迴文 if (typeof (str) !== 'string' || str.length === 0) { return false } let stack = new Stack() let oStr = str.toLocaleLowerCase() let nStr = '' for (let i = 0; i < str.length; i++) { stack.push(str[i]) } while (!stack.isEmpty()) { nStr += stack.pop().toLocaleLowerCase() } if (nStr === oStr) { // return `輸入的字串【{$oStr}】是迴文` return true } else { // return `輸入的字串【{$oStr}】不是迴文` return false } }
平衡括號
更多詳情請檢視原始碼
如果一個括號序列包含完整的左右括號對,則稱為平衡括號序列。如:"{[()]}","", "({})", "{()}"都是平衡括號,而"{()[]", ")"則不是平衡括號。
括號只有三種()/[]/{}
,每種分別有左右括號。我們可以這樣操作:遇到左括號,左括號入棧,遇到右括號,取出棧中最後一個括號來比對的方式來判斷是否相等平衡。
/**
* 判斷括號序列是否平衡,空序列也算是平衡
* @param {String} brackets 括號序列
*/
function balanceBracket(brackets) {
if (typeof (brackets) !== 'string') {
return false
}
let left = '([{'
let right = ')]}'
let num = 0 // 括號的對數
let stack = new Stack()
for (let i = 0; i < brackets.length; i++) {
if (right.indexOf(brackets[0]) > -1) {
return false
}
if (left.indexOf(brackets[i]) > -1) {
stack.push(brackets[i])
num++
} else {
if (right.indexOf(brackets[i]) > -1) {
let topBracket = stack.pop()
let rightSort = right.indexOf(brackets[i])
let leftSort = left.indexOf(topBracket)
if (rightSort !== leftSort) {
return false
}
}
}
}
return `是平衡括號序列。有${num}對括號`
}
漢諾塔
更多詳情請檢視原始碼
有三根相鄰的柱子,標號為A,B,C。A柱子上從下到上按金字塔狀疊放著n個不同大小的圓盤,要把所有圓盤移動到B柱子上。
要求:
- 每次只能移動一個圓盤。
- 每根柱子上的圓盤,下面的都比上面的大。
問題:
請問至少需要移動多少次圓盤?每次移動的步驟是怎樣的?
let num = 0 // 記錄移動的次數
/**
* 記錄圓盤移動的過程
*
* 這裡的思路,一直在迴圈做一件事情。
* 把原始柱子上的圓盤分為兩部分,最大和其它。
* 第一回合,將其它移動到輔助柱子上,將最大的移動到目標柱子上,再將其它移動到目標柱子上
* 第二回合,將其它移動到輔助柱子上,將最大的移動到目標柱子上,再將其它移動到目標柱子上
* ...
* 第2 ** n - 1回合,將其它移動到輔助柱子上,將最大的移動到目標柱子上,再將其它移動到目標柱子上
*
* 但是,這裡源柱子、輔助柱子和目標柱子會隨著其它盤而變動。
* 其它盤在哪個柱子上,哪根柱子就是源柱子。
* @param {Int32Array} plates 圓盤個數
* @param {Array} source 源柱子
* @param {Array} helper 輔助柱子
* @param {Array} dest 目的地柱子
* @param {String} sourceName 源柱子的名字
* @param {String} helperName 輔助柱子的名字
* @param {String} destName 目的地柱子的名字
* @param {Array} moves 步驟儲存器,儲存每一步的流程
*/
function moveOfHanoi(
plates,
source,
helper,
dest,
sourceName,
helperName,
destName,
moves = []
) {
if (plates <= 0) {
return moves
} else if (plates === 1) {
// 彈出源柱子上剩下的最大圓盤,並將其壓入目標柱子
dest.push(source.pop())
num++
let sourceArr = source.toString()
let helperArr = helper.toString()
let destArr = dest.toString()
let movestr = `第 ${num} 步,將圓盤 ${plates} 從 ${sourceName} 移至 ${destName}; ${sourceName}: [${sourceArr}],${helperName}: [${helperArr}],${destName}: [${destArr}]`
moves.push(movestr)
} else {
moveOfHanoi(
plates - 1,
source,
dest,
helper,
sourceName,
destName,
helperName,
moves
)
// 彈出源柱子上剩下的最大圓盤,並將其壓入目標柱子
dest.push(source.pop())
num++
let sourceArr = source.toString()
let helperArr = helper.toString()
let destArr = dest.toString()
let movestr = `第 ${num} 步,將圓盤 ${plates} 從 ${sourceName} 移至 ${destName}; ${sourceName}: [${sourceArr}],${helperName}: [${helperArr}],${destName}: [${destArr}]`
moves.push(movestr)
moveOfHanoi(
plates - 1,
helper,
source,
dest,
helperName,
sourceName,
destName,
moves
)
}
return moves
}
/**
* 漢諾塔
* 記錄每一次圓盤移動的動作。從${源柱子}到${目標柱子}
* @param {Int32Array} plates 圓盤的個數
* @param {String} sourceName 源柱子的名稱
* @param {String} helperName 輔助柱子的名稱
* @param {String} destName 目標柱子的名稱
*/
function hanoiStackArray(plates, sourceName, helperName, destName) {
let source = new Stack()
let helper = new Stack()
let dest = new Stack()
for (let i = plates; i > 0; i--) {
source.push(i)
}
num = 0
return moveOfHanoi(
plates,
source,
helper,
dest,
sourceName,
helperName,
destName
)
}
[完]
相關推薦
JavaScript資料結構和演算法 --- 棧
概念:表頭進行插入和刪除操作的線性表 核心思想:先進後出 作用:在程式語言的編譯器和記憶體中儲存變數、方法呼叫 操作方法:1)push() 進棧,即向棧裡新增元素 2)pop() 出棧,即把元素從棧中刪除
(考研必看)最全資料結構排序演算法效能分析與比較!!!
資料結構所有排序演算法效能分析與比較 轉載請標明出處weixin_44254963或璇小姐 通過對資料結構的學習,我發現數據結構中各種排序演算法的排序方法,過程,以及時間效能,空間效能都比較容易混淆,現就這些情況做如下總結,希望對大家有所幫助。 起泡排序(氣泡排序) 首先取第一個
資料結構及演算法--棧
順序棧 三個基本屬性 棧的儲存資料data 棧的最大儲存量maxSize 棧頂top Python實現 # Python 2.7 class sqStack(object): # 初始化 def __init__(self,
JS資料結構和演算法 --- 棧
概念:表頭進行插入和刪除操作的線性表 核心思想:先進後出 作用:在程式語言的編譯器和記憶體中儲存變數、方法呼叫 操作方法:1)push() 進棧,即向棧裡新增元素 &n
資料結構——使用Java棧實現【括號匹配】
給定一個只包括 '(',')','{','}','[',']'的字串,判斷字串是否有效。 有效字串需滿足: 左括號必須用相同型別的右括號閉合。 左括號必須以正確的順序閉合。 注意空字串可被認為是有效字串。 參考leetcode.com或leetcode-cn.com
資料結構用順序棧實現R進位制轉換
#include<stdio.h> #define MAXSIZE 500 typedef struct{ int *base; int *top; int stacksize; }Sqstack; int Initstack(Sqstack &S)
JavaScript資料結構和演算法
前言 在過去的幾年中,得益於Node.js的興起,JavaScript越來越廣泛地用於伺服器端程式設計。鑑於JavaScript語言已經走出了瀏覽器,程式設計師發現他們需要更多傳統語言(比如C++和Java)提供的工具。這些工具包括傳統的資料結構(如連結串列,棧,佇列,圖等),也包括傳統的排序和查詢演算法。
資料結構之用棧實現迷宮問題(dfs)
給一個n*n的方格,讓你求從左上角到所給一點的任意一條路徑並輸出 該題用到dfs,以下是對dfs的簡要解析 :詳解請參見 傳送門 dfs是一種用於遍歷或搜尋樹或圖的演算法。 沿著樹的深度遍歷樹的節點,儘可能深的搜尋樹的分支。當節點v的所在邊都己被探尋過或者在搜尋時結點不
JavaScript資料結構之隊棧互搏
今天稍微停下前進的腳步,來看下隊棧的左右互搏術。 前兩天學習了佇列和棧以後,今天就可以試著來用兩個棧實現佇列的功能 或者 用兩個佇列來實現棧的功能。 資料結構之---棧實現佇列 1. 用兩個棧實現一個佇列 1.1 題目分析 棧是先進後出,佇列是先進先出,但可以用兩個棧來模擬一個佇列的功能,來實現
【Java資料結構】用棧實現字尾表示式求值
今天在學資料結構,自己擼一段用棧來實現字尾表示式求值的程式碼,能改進的地方還有很多,在此先mark一下 package StackPractice; import java.util.Scanner; import java.util.Stack; im
資料結構——————排序演算法程式碼實現(未完待續......)
排序演算法 插入排序 折半插入排序 希爾排序 氣泡排序 快速排序 簡單選擇排序 堆排序 歸併排序(未完成) 基數排序(未完成) #include<bits/stdc++.h> using namespace
【資料結構】利用棧實現表示式求值
前言 java實現,利用int型別儲存運算元,完善了char類型範圍太小的問題,利用遞迴,完善了括號巢狀使用的問題。 執行結果截圖 程式碼實現: import java.util.Arrays; import java.util.Scanner; public
挑戰資料結構和演算法——棧的push、pop序列
題目來源“資料結構與演算法面試題80道”。在此給出我的解法,如你有更好的解法,歡迎留言。 問題分析:本題考查棧的基本操作,棧是一種“先進後出”的資料結構。判斷一個序列是否是棧的pop序列是
經典資料結構及演算法-Java實現-附原始碼(可下載)
閒暇之餘,將自己之前敲過的資料結構與演算法程式碼整理了一下,最後放在一個工程下面:具體分類:剛看了下專案目錄,少了排序分類介紹圖,在這裡補上(此圖來源於網上)最後,程式碼比較多,只展示下排序演算法的程式碼。package com.lzz.algorithm.sorting;
資料結構和演算法(Golang實現)(30)查詢演算法-2-3-4樹和普通紅黑樹
文章首發於 閱讀更友好的GitBook。 2-3-4樹和普通紅黑樹 某些教程不區分普通紅黑樹和左傾紅黑樹的區別,直接將左傾紅黑樹拿來教學,並且稱其為紅黑樹,因為左傾紅黑樹與普通的紅黑樹相比,實現起來較為簡單,容易教學。在這裡,我們區分開左傾紅黑樹和普通紅黑樹。 紅黑樹是一種近似平衡的二叉查詢樹,從2-3樹或2
資料結構和演算法(Golang實現)(25)排序演算法-快速排序
快速排序 快速排序是一種分治策略的排序演算法,是由英國電腦科學家Tony Hoare發明的, 該演算法被髮布在1961年的Communications of the ACM 國際計算機學會月刊。 注:ACM = Association for Computing Machinery,國際計算機學會,世界性的計
Javascript資料結構與演算法--棧的實現與用法
棧資料結構 棧是一種遵從後進先出(LIFO)原則的有序集合。新新增的或者待刪除的元素都儲存在棧的同一端,稱作棧頂,另一端就叫棧底。在棧裡,新元素都靠近棧頂,舊元素都接近棧底。 我們在生活中常能看到棧的例子。整齊堆起來的書,廚房堆起的盤子等 棧也被用在程式語言的編譯器和記憶體中儲存變數、方法呼叫等。 /**
為什麼我要放棄javaScript資料結構與演算法(第三章)—— 棧
有兩種結構類似於陣列,但在新增和刪除元素時更加可控,它們就是棧和佇列。 第三章 棧 棧資料結構 棧是一種遵循後進先出(LIFO)原則的有序集合。新新增的或待刪除的元素都儲存在棧的同一端,稱為棧頂,另一端就叫做棧底。在棧裡, 新元素都靠近棧頂,舊元素都接近棧底。 棧也被用在程式語言的編譯器和記憶體中儲存
javascript資料結構與演算法筆記(一):棧
javascript資料結構與演算法筆記(一):棧 一:簡介 二:ES6版Stack類(陣列) 三:ES版Stack類私有屬性的封裝 1.偽私有屬性封裝 2.真私有屬性封裝
python演算法與資料結構002--利用列表實現棧的功能
class Statck(object): """ 棧:後進先出的資料結構 利用列表實現棧的基本功能。 """ def __init__(self): self.items=[] def