介绍常见的数据结构,如集合、散列表、队列、栈、链表等,并用js来实现。
集合
集合是由一组无序且唯一的项组成。这个数据结构使用了与有限集合相同的数学概念,比如:自然数集合N={0,1,2,…}
集合会有一些运算,在本文也实现一下。
另外ES6中已经提出Set概念,API点击这里
|
|
字典
字典与集合的区别就是,字典存储的键值对,它也称作映射。
|
|
散列表
散列表实现是将key通过散列算法计算得到一个散列值,这样根据散列值直接查找效率要高,不需要像字典那样需要进行迭代。有时不同的key经过散列算法计算会得到相同的散列值,这种冲突解决的方案一般有链表法
、线性探测
。
链表法:为散列表的每一个位置创建一个链表并将元素存储在里面。他是解决冲突最简单的方法,但是他在HashTable实例之外需要额外的存储空间。Java中的HashMap就是采用链表法来解决hash冲突的。
线性探测:当向某个位置加入一个新元素的时候,如果索引为index的位置被占据了,就尝试index+1的位置,以此类推。
链表法实现
|
|
线性探测实现
|
|
栈
栈是一种遵循后进先出(LIFO)原则的有序集合。新增加的或待删除的都保存在栈的末尾,称作栈顶,另一端就叫栈底。
如下代码实现了一些栈的常用操作
|
|
队列
队列是遵循FIFO(First in first out,先进先出)
用ES6中class语法来实现该数据结构
|
|
然而在现实生活中,时常会有优先队列这种现象,如机场登机顺序,头等舱和商务舱乘客的优先级高于经济舱乘客。
只需要重写入队列的方法就可以实现优先队列
|
|
链表
链表存储有序的元素集合,但不同于数组,列表中的每个元素在内存中并不是连续放置的。每个元素有一个存储元素本身的节点和一个指向下一个元素的引用组成。
相对于数组,他的优点是添加或移除元素不需要移动其它元素。数组可以直接访问任何位置的任何元素,而想要访问链表中的元素,需要从起点开始迭代列表知道找到该元素为止。
单项链表:
|
|
双向链表
双向链表即包括指向下一个元素的指针,也包括指向上一个元素的指针。
|
|