快捷搜索:  汽车  科技

前端js框架推荐:前端 8种常见数据结构及其JS实现

前端js框架推荐:前端 8种常见数据结构及其JS实现Javascript中的Array已经具备了Queue的一些特性,所以我们可以借助Array实现一个Queue类型:Queue一般具有以下常见方法:Javascript的Array天生具备了Stack的特性,但我们也可以从头实现一个 Stack类:function Stack() { this.count = 0; this.storage = {}; this.push = function (value) { this.storage[this.count] = value; this.count ; } this.pop = function () { if (this.count === 0) { return undefined; } this.count--; var result = this.storage[this.count]; delete

做前端的同学不少都是自学成才或者半路出家,计算机基础的知识比较薄弱,尤其是数据结构和算法这块,所以今天整理了一下常见的数据结构和对应的Javascript的实现,希望能帮助大家完善这方面的知识体系。

1. Stack(栈)

前端js框架推荐:前端 8种常见数据结构及其JS实现(1)

Stack的特点是后进先出(last in first out)。生活中常见的Stack的例子比如一摞书,你最后放上去的那本你之后会最先拿走;又比如浏览器的访问历史,当点击返回按钮,最后访问的网站最先从历史记录中弹出。

Stack一般具备以下方法:

  1. push:将一个元素推入栈顶
  2. pop:移除栈顶元素,并返回被移除的元素
  3. peek:返回栈顶元素
  4. length:返回栈中元素的个数

Javascript的Array天生具备了Stack的特性,但我们也可以从头实现一个 Stack类:

function Stack() { this.count = 0; this.storage = {}; this.push = function (value) { this.storage[this.count] = value; this.count ; } this.pop = function () { if (this.count === 0) { return undefined; } this.count--; var result = this.storage[this.count]; delete this.storage[this.count]; return result; } this.peek = function () { return this.storage[this.count - 1]; } this.size = function () { return this.count; } }

2. Queue(队列)

前端js框架推荐:前端 8种常见数据结构及其JS实现(2)

Queue和Stack有一些类似,不同的是Stack是先进后出,而Queue是先进先出。Queue在生活中的例子比如排队上公交,排在第一个的总是最先上车;又比如打印机的打印队列,排在前面的最先打印。

Queue一般具有以下常见方法:

  1. enqueue:入列,向队列尾部增加一个元素
  2. dequeue:出列,移除队列头部的一个元素并返回被移除的元素
  3. front:获取队列的第一个元素
  4. isEmpty:判断队列是否为空
  5. size:获取队列中元素的个数

Javascript中的Array已经具备了Queue的一些特性,所以我们可以借助Array实现一个Queue类型:

function Queue() { var collection = []; this.print = function () { console.log(collection); } this.enqueue = function (element) { collection.push(element); } this.dequeue = function () { return collection.shift(); } this.front = function () { return collection[0]; } this.isEmpty = function () { return collection.length === 0; } this.size = function () { return collection.length; } }

Priority Queue(优先队列)

Queue还有个升级版本,给每个元素赋予优先级,优先级高的元素入列时将排到低优先级元素之前。区别主要是enqueue方法的实现:

function PriorityQueue() { ... this.enqueue = function (element) { if (this.isEmpty()) { collection.push(element); } else { var added = false; for (var i = 0; i < collection.length; i ) { if (element[1] < collection[i][1]) { collection.splice(i 0 element); added = true; break; } } if (!added) { collection.push(element); } } } }

测试一下:

var pQ = new PriorityQueue(); pQ.enqueue(['gannicus' 3]); pQ.enqueue(['spartacus' 1]); pQ.enqueue(['crixus' 2]); pQ.enqueue(['oenomaus' 4]); pQ.print();

结果:

[ [ 'spartacus' 1 ] [ 'crixus' 2 ] [ 'gannicus' 3 ] [ 'oenomaus' 4 ] ]

3. Linked List(链表)

前端js框架推荐:前端 8种常见数据结构及其JS实现(3)

顾名思义,链表是一种链式数据结构,链上的每个节点包含两种信息:节点本身的数据和指向下一个节点的指针。链表和传统的数组都是线性的数据结构,存储的都是一个序列的数据,但也有很多区别,如下表:

比较维度数组链表内存分配

静态内存分配,编译时分配且连续

动态内存分配,运行时分配且不连续

元素获取

通过Index获取,速度较快

通过遍历顺序访问,速度较慢

添加删除元素

因为内存位置连续且固定,速度较慢

因为内存分配灵活,只有一个开销步骤,

速度更快

空间结构

可以是一维或者多维数组

可以是单向、双向或者循环链表

一个单向链表通常具有以下方法:

  1. size:返回链表中节点的个数
  2. head:返回链表中的头部元素
  3. add:向链表尾部增加一个节点
  4. remove:删除某个节点
  5. indexOf:返回某个节点的index
  6. elementAt:返回某个index处的节点
  7. addAt:在某个index处插入一个节点
  8. removeAt:删除某个index处的节点

单向链表的Javascript实现:

/** * 链表中的节点 */ function Node(element) { // 节点中的数据 this.element = element; // 指向下一个节点的指针 this.next = null; } function LinkedList() { var length = 0; var head = null; this.size = function () { return length; } this.head = function () { return head; } this.add = function (element) { var node = new Node(element); if (head == null) { head = node; } else { var currentNode = head; while (currentNode.next) { currentNode = currentNode.next; } currentNode.next = node; } length ; } this.remove = function (element) { var currentNode = head; var previousNode; if (currentNode.element === element) { head = currentNode.next; } else { while (currentNode.element !== element) { previousNode = currentNode; currentNode = currentNode.next; } previousNode.next = currentNode.next; } length--; } this.isEmpty = function () { return length === 0; } this.indexOf = function (element) { var currentNode = head; var index = -1; while (currentNode) { index ; if (currentNode.element === element) { return index; } currentNode = currentNode.next; } return -1; } this.elementAt = function (index) { var currentNode = head; var count = 0; while (count < index) { count ; currentNode = currentNode.next; } return currentNode.element; } this.addAt = function (index element) { var node = new Node(element); var currentNode = head; var previousNode; var currentIndex = 0; if (index > length) { return false; } if (index === 0) { node.next = currentNode; head = node; } else { while (currentIndex < index) { currentIndex ; previousNode = currentNode; currentNode = currentNode.next; } node.next = currentNode; previousNode.next = node; } length ; } this.removeAt = function (index) { var currentNode = head; var previousNode; var currentIndex = 0; if (index < 0 || index >= length) { return null; } if (index === 0) { head = currentIndex.next; } else { while (currentIndex < index) { currentIndex ; previousNode = currentNode; currentNode = currentNode.next; } previousNode.next = currentNode.next; } length--; return currentNode.element; } }

4. Set(集合)

前端js框架推荐:前端 8种常见数据结构及其JS实现(4)

集合是数学中的一个基本概念,表示具有某种特性的对象汇总成的集体。在ES6中也引入了集合类型Set,Set和Array有一定程度的相似,不同的是Set中不允许出现重复的元素而且是无序的。

一个典型的Set应该具有以下方法:

  1. values:返回集合中的所有元素
  2. size:返回集合中元素的个数
  3. has:判断集合中是否存在某个元素
  4. add:向集合中添加元素
  5. remove:从集合中移除某个元素
  6. union:返回两个集合的并集
  7. intersection:返回两个集合的交集
  8. difference:返回两个集合的差集
  9. subset:判断一个集合是否为另一个集合的子集

使用Javascript可以将Set进行如下实现,为了区别于ES6中的Set命名为MySet:

function MySet() { var collection = []; this.has = function (element) { return (collection.indexOf(element) !== -1); } this.values = function () { return collection; } this.size = function () { return collection.length; } this.add = function (element) { if (!this.has(element)) { collection.push(element); return true; } return false; } this.remove = function (element) { if (this.has(element)) { index = collection.indexOf(element); collection.splice(index 1); return true; } return false; } this.union = function (otherSet) { var unionSet = new MySet(); var firstSet = this.values(); var secondSet = otherSet.values(); firstSet.forEach(function (e) { unionSet.add(e); }); secondSet.forEach(function (e) { unionSet.add(e); }); return unionSet; } this.intersection = function (otherSet) { var intersectionSet = new MySet(); var firstSet = this.values(); firstSet.forEach(function (e) { if (otherSet.has(e)) { intersectionSet.add(e); } }); return intersectionSet; } this.difference = function (otherSet) { var differenceSet = new MySet(); var firstSet = this.values(); firstSet.forEach(function (e) { if (!otherSet.has(e)) { differenceSet.add(e); } }); return differenceSet; } this.subset = function (otherSet) { var firstSet = this.values(); return firstSet.every(function (value) { return otherSet.has(value); }); } }

5. Hash Table(哈希表/散列表)

前端js框架推荐:前端 8种常见数据结构及其JS实现(5)

猜您喜欢: