几个常用的数据结构:
- 数组
- HTMLCollection
- NodeList
- 对象
- Set
- Map
- 二叉树
- 链表
数组 Array
数组的特点:
- 数据必须按照索引顺序依次排列,数组是根据索引放入数据,同样可以根据索引值找到数据;
- 数组是一个紧密型结构,如果要删除,添加,插入都需要重新排列每个元素,会涉及到时间复杂度;
- 数组中的元素都是有关系的,可以从找到这个元素向上或者向下找到关联位置的元素 ;
- 数组中存储元素的总量是一个可变值,当添加或者删除元素时,总量都会改变;
- 数组长度改变也会引起数组元素的改变;
- 数组被创建出大量的方法来使用它,造成API过多;
- 数组查找元素时需要遍历,所以数组的查找速度是非常慢的,效率特别慢;
var arr=[1,2,3,4];
console.log(arr);//打印结果如下
使用数组时需要注意的地方:
- js数组不好地方 长度可变 元素类型复杂
- 尽量让数组的元素类型保持统一;
- 尽量在设置时设置数组的初始长度(var arr=new Array(50)),尽量不要超出长度;
- 数组适合使用的场景:列表形式、简单的、增删变化少的、有顺序的;
HTMLCollection
html 元素集合。
<span></span><span></span><span name="abc"></span>
<script>
var span=document.getElementsByTagName("span");
console.log(span.length);//3
console.log(span.item(1));//<span></span> 获取下标为1的元素,下标从0开始
console.log(span.namedItem("abc"));//<span name="abc"></span> 获取name为abc的元素
console.log(span);//打印如果如下
</script>
NodeList
对象原型链中有 iterator 这个接口的,都可以用for of遍历。
<div class="div0" name="aa">1</div>
<div class="div0" name="bb">2</div>
<div class="div0" name="cc">3</div>
<script>
var div=document.querySelectorAll(".div0");
console.log(div);//打印结果如下
for(let value of div){
console.log(value);//打印出每个div元素
}
</script>
对象 object
对象的特点:
- 对象是无序的,没有长度的;
- 对象因为没有索引,所以使用key=>value,键值对形式来存储;
- 对象中键是不能重复,只要知道键就可以快速找到值;
- 对象中的所有key都是无序的,意味着不能按照顺序遍历;
- 所有数据都是没有关联的,没有上下直接的概念;
- 对象适合使用的场景:数据相互间没有关系,无序的,键值形式,需要根据键查找值的,对数据进行分类;
- 原生js中对象是根据属性创建的先后顺序进行遍历的;
- 当key是数值时,对象会按照数值顺序自动排列好,当key是数值和字符交叉时,优先排序数值;
var obj={a:1,b:2}
console.log(obj);//打印结果如下
当需要在对象的第一项插入数据时,可以新建一个对象,将值依次写入。
var obj={
a:1,
b:2,
c:3
}
var o={
z:0,
a:obj.a,
b:obj.b,
c:obj.c
}
for(var prop in o){
console.log(prop);
}
当key是数值时,会按照顺序自动排列好,根据这一特点,可以进行数组的桶排序。
let arr=[2,5,7,1,4,3,6,8,0];
let obj={};
arr.forEach(item=>obj[item]=item);
arr.length=0;
for(let prop in obj){
arr.push(obj[prop]);
}
console.log(arr);//[0,1,2,3,4,5,6,7,8]
点击查看Set、Map的详细内容:https://blog.csdn.net/Charissa2017/article/details/103937710
Set
- Set是无序的,不重复的;
- Set是有长度的,使用size获取;
- Set不能按照键值对查找,也不能按照索引查找,只能遍历查找;
- Set插入、删除、添加的速度极快
- Set的API特别简单;
var set=new Set([1,2,3,4,5]);
console.log(set);//打印如果如下
WeakSet
WeakSet 是弱引用列表,WeakSet和Set结构类似, 同样不会存储重复的值,不同的是,它的成员必须是对象类型的值。
var weakSet=new WeakSet();
weakSet.add({a:1});
weakSet.add({b:2});
console.log(weakSet);//打印结果如下
Map
- Map是键值对存储;
- Map是有长度的,使用size获取;
- 可以只遍历值,也可以只遍历键,查找值操作简便;
- 添加、删除、插入、查找速度快;
let map=new Map();
map.set("name","xiaoming");
map.set("age",18);
map.set("sex","man");
for(let value of m.values()){
console.log(value);//只遍历值
}
for(let prop of m.keys()){
console.log(prop);//只遍历键
}
console.log(map);//打印结果如下
WeakMap
普通的map不能使用对象作为属性存储值,WeakMap可以使用对象作为属性存储值。WeakMap 是弱引用类型。
let weakMap=new WeakMap();
weakMap.set({a:1},"bb");
console.log(weakMap);//打印结果如下
二叉树
二叉树是递归定义的,二叉树是每个结点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。
javascript 实现二叉树:
class Tree{
left=null;
right=null;
value=null;
constructor(_value){
this.value=_value;
}
}
class Trees{
constructor(){
this.root=null;
}
insert(value){
let tree=new Tree(value);
if(!this.root){
this.root=tree;
}else{
this.inserTree(this.root,tree);
}
}
inserTree(tree,newTree){
if(newTree.value<tree.value){
if(tree.left){
this.inserTree(tree.left,newTree);
}else{
tree.left=newTree;
}
}else{
if(tree.right){
this.inserTree(tree.right,newTree);
}else{
tree.right=newTree;
}
}
}
}
let tree=new Trees();
for(let i=20;i>0;i-=2){
tree.insert(i-1);
tree.insert(i);
}
console.log(tree);
链表
链表是一种物理存储单元上非连续、非顺序的存储结构。
数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。
链表的特点:
- 插入、删除数据非常快捷;
- 遍历查找相对较慢,和数组遍历复杂度相似;
- 双向链表 前后关联查找;
示意图: