什么是数据结构:数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。数据结构往往同高效的检索算法和索引技术有关;
栈(Stack)
什么是栈:栈是一种高效的数据结构(后进先出(LIFO)原则的有序集合),因为数据只能在栈顶添加或删除,所以这样的操作很快,而且容易实现。
场景:编程语言中的编译器、计算机内存存储变量和方法调用,浏览器的后退功能等等;
Stack包含以下方法
- push(e):将新添加的元素添加至堆栈的顶部
- pop():删除栈顶的元素,同时返回已删除的元素
- peek():返回堆栈的顶部元素
- isEmpty():判断堆栈是否为空,如果为空返回true
- clear(): 清空堆栈所有的元素
- size(): 返回堆栈元素的数量,类似数组的长度
- toArray():以数组的形式返回堆栈的元素
- toString(): 以字符串的形式输出堆栈的内容;
由于数组是有序数组,如果存储大数据内容过多的话,会消耗更多的计算机内存,算法的复杂度就会增加,为了解决此类问题,建议使用对象的形式;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| export default class Stack { constructor() { this.count = 0; this.items = {}; } push(element) { this.items[this.count] = element; this.count++; } pop() { if (this.isEmpty()) { return undefined; } this.count--; const result = this.items[this.count]; delete this.items[this.count]; return result; } peek() { if (this.isEmpty()) { return undefined; } return this.items[this.count - 1]; } isEmpty() { return this.count === 0; } size() { return this.count; } clear() {
this.items = {}; this.count = 0; } 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; } }
|
以上方法在Stack类中声明的items和count属性是不受保护的,可以使用symbol数据类型作为对象的属性具有私有性的特点,改变以上属性;
1 2 3 4 5 6 7 8 9 10 11
| const _items = Symbol('stack') 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} size(){return this[_items].length} clear(){this[_items] = []} toString(){return this[_items].toString()} }
|
实际应用举例
实现一个十进制转换二进制的功能,在与计算机进行通信必须使用二进制的功能,如果需要转换2进制需要将转换的数字除以2,再将结果除以2,如此循环,直到结果为0为止;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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) } while(!remStack.isEmpty()){ binaryString += remStack.pop().toString() } return binaryString }
|
链表(Linked List)
链表是一个线性结构,同时也是一个天然的递归结构,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理,但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大;
为何要使用链表:因为数组有缺陷,增删元素时往往需要移动元素,而链表在内存中的放置并不是连续的,元素通过next属性指向下个元素,所以链表增删元素,不需要移动元素,只需要更改next的指向即可;
使用场景:在javascript中,最重要的链:作用域链和原型链;
链表的创建:
首先创建一个用来保存链表里的数据
1 2 3 4 5 6 7 8 9
|
function Node(element){ this.element = element; this.next = null }
|
链表的方法:
append
(element):向链表尾部添加一个新的元素
insert
(position,element):向链表特定位置插入元素
remove
(element): 从链表移除一项
indexOf
(element): 返回链表中某元素的索引,如果没有返回-1
removeAt
(position):从特定位置移除一项
isEmpty
(): 判断链表是否为空,如果为空返回true
size
(): 返回链表包含的元素个数
toString
():重写继承Object类的tostring方法,因为我们使用了Node类;