js创建链表
首先要明确,我们为什么要创建链表呢?数组的大小是固定的,从数组的起点或中间插入或移除的成本很高,因为需要移动元素。尽管JS的Array类方法可以做这些,但是情况也是这样。链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身和指向下一个元素的指针组成。
相对于传统的数组,链表的一个好处在于,添加或移除元素的时候不需要移动其他元素。然而,链表需要使用指针,因此实现链表时需要额外注意。数组的另一个细节是可以直接访问任何位置的任何元素,而要想访问链表中间的一个元素,需要从起点(表头)开始迭代到列表直到找到所需元素。
好了,闲话少叙,正式创建链表!
我们使用动态原型模式来创建一个链表。列表最后一个节点的下一个元素始终是null。
function LinkedList() {
//先创建一个节点
function Node(element) {
this.element = element;
this.next = null;
}
this.head = null;
this.length = 0;
//通过对一个方法append判断就可以知道是否设置了prototype
if ((typeof this.append !== 'function') && (typeof this.append !== 'string')) {
//添加元素
LinkedList.prototype.append = function(element) {
var node = new Node(element);
var current;
if (this.head == null) {
this.head = node;
} else {
current = this.head;
while (current.next != null) {
current = current.next;
}
current.next = node;
}
this.length++;
};
//插入元素,成功true,失败false
LinkedList.prototype.insert = function(position, element) {
if (position > -1 && position < this.length) {
var current = this.head;
var node = new Node(element);
var previous;
var index = 0;
if (position == 0) {
node.next = current;
this.head = node;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
node.next = current;
previous.next = node;
}
this.length++;
return true;
} else {
return false;
}
};
//根据位置删除指定元素,成功 返回元素, 失败 返回null
LinkedList.prototype.removeAt = function(position) {
if (position > -1 && position < this.length) {
var current = this.head;
var previous = null;
var index = 0;
if (position == 0) {
this.head = current.next;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
previous.next = current.next;
}
this.length--;
return current.element;
} else {
return null;
}
};
//根据元素删除指定元素,成功 返回元素, 失败 返回null
LinkedList.prototype.remove = function(element) {
var index = this.indexOf(element);
return this.removeAt(index);
};
//返回给定元素的索引,如果没有则返回-1
LinkedList.prototype.indexOf = function(element) {
var current = this.head;
var index = 0;
while (current) {
if (current.element === element) {
return index;
}
current = current.next;
index++;
}
return -1;
};
LinkedList.prototype.isEmpty = function() {
return this.length === 0;
};
LinkedList.prototype.size = function() {
return this.length;
};
LinkedList.prototype.toString = function() {
var string = '';
var current = this.head;
while (current) {
string += current.element;
current = current.next;
}
return string;
};
LinkedList.prototype.getHead = function() {
return this.head;
};
}
}
链表的基本使用
var linkedList = new LinkedList();
console.log(linkedList.isEmpty());//true;
linkedList.append('huang');
linkedList.append('du')
linkedList.insert(1,'cheng');
console.log(linkedList.toString());//huangchengdu
console.log(linkedList.indexOf('du'));//
console.log(linkedList.size());//
console.log(linkedList.removeAt(2));//du
console.log(linkedList.toString());//huangcheng
创建双向链表
在双向链表中,链接是双向的:一个链向下一个元素, 另一个链向前一个元素。
双向链表和链表的区别就是有一个tail属性,所以必须重写insert、append、removeAt方法。每个节点对应的Node也多了一个prev属性。
//寄生组合式继承实现,详见javascript高级程序设计第七章
function inheritPrototype(subType, superType) {
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
var prototype = object(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
function DoublyLinkedList() {
function Node(element) {
this.element = element;
this.next = null;
this.prev = null;
}
this.tail = null;
LinkedList.call(this);
//与LinkedList不同的方法自己实现。
this.insert = function(position, element) {
if (position > -1 && position <= this.length) {
var node = new Node(element);
var current = this.head;
var previous;
var index = 0;
if (position === 0) {
if (!this.head) {
this.head = node;
this.tail = node;
} else {
node.next = current;
current.prev = node;
this.head = node;
}
} else if (position == this.length) {
current = this.tail;
current.next = node;
node.prev = current;
this.tail = node;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
previous.next = node;
node.next = current;
current.prev = node;
node.prev = previous;
}
this.length++;
return true;
} else {
return false;
}
};
this.append = function(element) {
var node = new Node(element);
var current;
if (this.head === null) {
this.head = node;
this.tail = node;
} else {
current = this.head;
while (current.next !== null) {
current = current.next;
}
current.next = node;
node.prev = current;
this.tail = node;
}
this.length++;
};
this.removeAt = function(position) {
if (position > -1 && position < this.length) {
var current = this.head;
var previous;
var index = 0;
if (position === 0) {
this.head = current.next;
if (this.length === 1) {
this.tail = null;
} else {
this.head.prev = null;
}
} else if (position === (this.length - 1)) {
current = this.tail;
this.tail = current.prev;
this.tail.next = null;
} else {
while (index++ < position) {
previous = current;
current = current.next;
}
previous.next = current.next;
current.next.prev = previous;
}
this.length--;
return current.element;
} else {
return false;
}
};
}
inheritPrototype(DoublyLinkedList, LinkedList);
双向链表的基本使用
var doublyList = new DoublyLinkedList();
console.log(doublyList.isEmpty()); //true;
doublyList.append('huang');
doublyList.append('du')
doublyList.insert(1, 'cheng');
console.log(doublyList.toString()); //huangchengdu
console.log(doublyList.indexOf('du')); //
console.log(doublyList.size()); //
console.log(doublyList.removeAt(2)); //du
console.log(doublyList.toString()); //huangcheng
js创建链表的更多相关文章
- js 实现链表
我们通常会在c++这类语言中学习到链表的概念,但是在js中由于我们可以动态的扩充数组,加之有丰富的原生api.我们通常并不需要实现链表结构.由于突发奇想,我打算用js实现一下: 首先我们要创建链表: ...
- 用Backbone.js创建一个联系人管理系统(五)
原文: Build a Contacts Manager Using Backbone.js: Part 5 这是这系列教程最后一部分了. 之前所有的增删改都在前端完成. 这部分我们要把Contact ...
- 使用 iosOverlay.js 创建 iOS 风格的提示和通知
iosOverlay.js 用于在 Web 项目中实现 iOS 风格的通知和提示效果.为了防止图标加载的时候闪烁,你需要预加载的图像资源.不兼容 CSS 动画的浏览器需要 jQuery 支持.浏览器兼 ...
- Dynamics.js - 创建逼真的物理动画的 JS 库
Dynamics.js 是一个用来创建物理动画 JavaScript 库.你只需要把dynamics.js引入你的页面,然后就可以激活任何 DOM 元素的 CSS 属性动画,也可以用户 SVG 属性. ...
- 使用three.js创建3D机房模型-分享一
序:前段时间公司一次研讨会上,一市场部同事展现了同行业其他公司的3D机房,我司领导觉得这个可以研究研究,为了节约成本,我们在网上大量检索,最后找到一位前辈的博文[TWaver的技术博客],在那篇博文的 ...
- Node.js 创建HTTP服务器
Node.js 创建HTTP服务器 如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi. 从这个角度看,整个& ...
- 用Backbone.js创建一个联系人管理系统(一)
原文 Build a Contacts Manager Using Backbone.js: Part 1 在这个教程里我们将会使用Backbone.js,Underscore.js,JQuery创建 ...
- Node.js 创建HTTP服务器(经过测试,这篇文章是靠谱的T_T)
Node.js 创建HTTP服务器 如果我们使用PHP来编写后端的代码时,需要Apache 或者 Nginx 的HTTP 服务器,并配上 mod_php5 模块和php-cgi. 从这个角度看,整个& ...
- js创建元素
js创建多条数据,插入到页面中的方法. 方法一: 执行时间大概在35ms左右. 这个就属于使用字符串拼接之后,再一次性的插入到页面中.缺点是,容易导致事件难以绑定. 方法二: 执行时间不定,最少的在8 ...
随机推荐
- 张小龙用这8句话表达了NB产品的一切(转)
1.一个好的产品应该是用完即走 真正好的产品,应该是让用户提高效率而不是消磨时光.但现在大部分用户使用微信的时间让我们很担忧. 包括我们自己的同事,在开会的时候,有同事隔两分钟就看一下手机,我觉得他们 ...
- vue-动态路由+动态组件+动态页面
动态路由 路由组件是vue-router 动态路由即从后端请求路由信息,然后转化生成路由信息.所以这里的关键是不会提前知道什么菜单对应什么组件,因此路由声明的时候不再是写死的组件,而是可替换的动态路径 ...
- 关于dataset
举个栗子: <div id="cost" data-drink="coffee" data-food="sushi" data-mea ...
- QT版本下载链接
http://download.qt.io/archive/qt/
- 获取impala下所有的数据库建表语句
方法一: 现在的导出还是有缺陷的,导出的文件中还是存在其他不必要的信息 #!/bin/bash ##获取数据库 databases=$(hive -e "show databases; ex ...
- PHP扩展模块php_igbinary和php_redis的安装
php_igbinary : 在序列化和反序列化的效率上高于其自带的 php_redis :效率是相当高有链表排序功能 详情略 安装之前要准备 百度网盘: wampserver2.5-A ...
- select * 和 select 字段的速度对比
拿WordPress的数据库做一个对比 SELECT ID,post_title, post_author FROM wp_posts ORDER BY ID LIMIT 100; OK, Time: ...
- 01_Hive简介及其工作机制
1.Hive简介 Hive是一个基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一个表.并提供类SQL查询功能, 可以将sql语句转换为MapReduce任务运行.其优点是学习成本低, ...
- PAT乙级1043
题目链接 https://pintia.cn/problem-sets/994805260223102976/problems/994805280074743808 题解 这次再次体会到题意理解的正确 ...
- easyui tree选中指定节点,点击指定节点
功能需求描述如下: A主页面,在datagrid的某行上,操作列,点击详情,Tab页面上加载B页面 B页面,左边是树tree,右边是左边树的详情列表 要求:由A页面链接到B页面,B页面的tree,默认 ...