数据结构学习-数组、栈和队列

### 数组 数组是最简单的内存数据结构,由于其简单性和灵活性,很多编程语言都内置数组,JS当然也支持。关于数组的介绍可参考以下文章 [数组基础学习](https://blog.86886.wang/posts/5aed8d6c2e528d4914d62144) [数组方法学习](https://blog.86886.wang/posts/5af048272e528d4914d62146) ### 栈 栈是一种遵从后进先出(LIFO)原则的有序集合。新添加的或待删除的元素都保存在栈的 同一端,称作栈顶,另一端就叫栈底。在栈里,新元素都靠近栈顶,旧元素都接近栈底。 在现实生活中也能发现很多栈的例子,比如一摞书,最新的书在最上面,取书的时候也是先取最上面。栈也被用在编程语言的编译器和内存中保存变量、方法调用等。JS是一门解释性语言,编译过程是由浏览器完成的,JS中的原始值都是在栈中存储的 利用数组的push和pop方法,可以很方面的模拟栈数据结构 首先为栈声明一些方法 ``` push(element(s)) :添加一个(或几个)新元素到栈顶。 pop() :移除栈顶的元素,同时返回被移除的元素。 peek() :返回栈顶的元素,不对栈做任何修改(这个方法不会移除栈顶的元素,仅仅返 回它)。 isEmpty() :如果栈里没有任何元素就返回 true ,否则返回 false 。 clear() :移除栈里的所有元素。 size() :返回栈里的元素个数。这个方法和数组的 length 属性很类似。 ``` 实现声明的方法 ```js class Stack { constructor () { this.items = []; //{1} } 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.length; } } // 使用 let s = new Stack(); s.push('a'); ``` 这种方式实现的栈结构有个缺点,由于items是公有属性,导致外部能随意操作items中的值。这样实现的栈本质上和数组没什么区别,所以要想办法把items变成私有属性,一个比较简单的方法是使用ES6的WeakMap ```js let Stack = (function(){ const items = new WeakMap(); class Stack { constructor() { items.set(this, []); } //其他方法 } return Stack; })() ``` 除此之外,也可以通过特权方法达到属性私有化的目的 ```js function Stack() { let items = []; // 私有属性 this.push = function(element) { // 特权方法 items.push(element) } // 其他方法 } let s = new Stack(); s.push('a'); ``` #### 应用 使用栈结构实现十进制转二进制 ```js function divideBy2(decNumber){ var remStack = new Stack, rem, binaryString = ''; while (decNumber > 0){ rem = Math.floor(decNumber % 2); remStack.push(rem); decNumber = Math.floor(decNumber / 2); } while (!remStack.isEmpty()){ binaryString += remStack.pop().toString(); } return binaryString; } divideBy2(10); // '1010' ``` ### 队列 队列是遵循FIFO(First In First Out,先进先出,也称为先来先服务)原则的一组有序的项。 队列在尾部添加新元素,并从顶部移除元素。最新添加的元素必须排在队列的末尾。 在现实中,最常见的队列的例子就是排队,比如在电影院、自助餐厅、杂货店收银台,排在第一位的人会先接受服务,服务完成后先离开 使用数组的push和shift方法可以模拟这种数据结构 队列要实现的方法 ``` enqueue(element(s)) :向队列尾部添加一个(或多个)新的项。 dequeue() :移除队列的第一(即排在队列最前面的)项,并返回被移除的元素。 front() :返回队列中第一个元素——最先被添加,也将是最先被移除的元素。 isEmpty() :如果队列中不包含任何元素,返回 true ,否则返回 false 。 size() :返回队列包含的元素个数,与数组的 length 属性类似。 ``` 使用ES6实现队列 ```js let Queue = (function(){ let items = new WeakMap(); class Queue { constructor() { items.set(this, []); } enqueue() { this.items.push(element); } dequeue() { return this.items.shift(); } front() { return this.items[0]; } isEmpty() { return this.items.length === 0; } size() { return this.items.length; } } return Queue; })() ``` 使用ES5实现队列 ```js function Queue() { let items = []; this.enqueue = function(element){ items.push(element); }; // 其他方法 } ```
上一篇:如何使用相同的TLS会话连接到具有数据连接的FTPS服务器?


下一篇:如何用PHP在sftp-server上编写文件?