JavaScript 数据结构(一): 链表

前言

从实用性角度来说,链表对Javascript 来说没有任何价值,为什么呢?
我们先了解链表的特性,这个特性我们放在c++前提下来说,因为 这个特性是 根据 内存特性 来阐述的,Javascript 不存在内存操作,所有数据类型,本质性继承Object 对象,而Object对象,其实可以说是一个哈希存储(资料传送门) ,所以链表对于 JavaScript毫无价值。 当然下文会提供一些例子,来证明这个结论

结构

链表以头节点开始(head),以next 属性链接下一个节点。

链表以索引方向分为:

  1. 单向链表,从头到尾 单方向索引。
  2. 双向链表,可以从头部想尾部索引,也能重尾部向头部索引
  3. 循环列表,头指针指向尾节点, 尾指针指向头结点

下图 为单向链表的 结构
这里写图片描述

特性

对于链表的特性只有2个,这两个特性 只能体现在高级语言当中。

  • 链表动态的大小(长度动态分配)
  • 能高性能插入,删除元素

链表动态的大小
数组是初始化的时候就分配好固定大小,在内存当中,这块分配好的空间表现是 连续固定的,但是链表不一样,链表的节点是分散的,通过程序链接的。

能高性能插入,删除元素
链表的高性能的插入/删除元素,也是因为对应内存特性。由于数组的 固定连续的内存空间,数组的索引速度很快,但是插入/删除性能不好,因为每当做插入/删除操作都会让其他元素移动内存地址,而链表就是控制节点的 指针就是 进行插入/删除。

关于JavaScript 的链表

前言提过 链表这个结构对JavaScript毫无意义,为什么呢。

链表的特性在JavaScript中完全体现不出,JavaScript的数组,本身就不是传统的数组,JS的数组其实就是JS Object 对象的拓展,而JS Object 在 C++ 中其实是用Hash Map的实现的。关于JS Obect详细资料传送门

当然抱着学习与探索的精神,我们还是用JavaScript 实现了 链表。

实现源码

// 节点对象
function Node(element) {
  this.element = element;
  this.next = null;
}

// 列表对象
function List() {
  this.head = new Node("head");
  this.find = find;
  this.insert = insert;
  this.remove = remove;
  this.display = display;
  this.findPrevious = findPrevious;
}

// 搜索元素方法
function find(item) {
  let currNode = this.head;
  while(currNode.element !== item) {
    currNode = currNode.next;
  }
  return currNode;
}

// 插入元素方法
function insert(newElement,item) {
  let newNode = new Node(newElement);
  let current = this.find(item);
  if(current === null)
    return console.log("can't find the item");
  newNode.next = current.next;
  current.next = newNode;
}

// 移除元素方法
function remove(item) {
  let prevNode = this.findPrevious(item);
  if(prevNode.next !== null)
    prevNode.next = prevNode.next.next;

}

// 查找item 的前节点
function findPrevious(item) {
  let currNode = this.head;
  while(currNode.next !== null && currNode.next.element !== item) {
    currNode = currNode.next;
  }
  return currNode;
}

// 显示列表数据
function display() {
  let current = this.head;
  while(current.next !== null) {
    console.log(current.next.element);
    current = current.next;
  }
}

测试性能

上文提及链表插入性能优秀,我们运行下面代码

let l = new List();
let arr = [];

console.time();
for(let i =0 ; i< 100000; i++){
  arr.push(i)
}
console.timeEnd();

console.time();
for(let i =1 ; i< 100000; i++){
  l.insert(i, 'head')
}
console.timeEnd();

结果是:

这里写图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值