javascript linkedlist data structures
在使用C++的时候我们经常会使用到各种容器,这些容器其实就是一种数据结构。在java中其实也是如此。但是由于javascript只给我们提供了一种内置的数据结构数组,准备来说是对象。没有我们常见的那些数据结构,但是在实际的工作中我们却不能离开这些常见的数据结构。所以我们只能去自己构造了。
虽然javascript中的数组的操作,比C++/java等操作数组方便的多,但是毕竟数组是一种对象,在对数据进行处理的时候效率还是很低的。所以有时候我们要自己构造想要的数据结构了。
定义(define):
链表是有一组节点组成的集合。每个节点都包含两部分:第一部分是存储数据元素的数据域,另一个是存储下一个结点地址的引用域。每个节点都会使用一个对象的引用来指向他的后继节点。这个对后继对象的引用就是我们常说的链。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。因此在除了对数据元素的随机访问使用数组外,其他情况下在使用一位数组的地方,都可以使用链表。

我们知道数组主要是靠位置来进行引用元素的,而链表则是通过彼此之间的关系来引用的。在我们想查找一个再链表中的元素的时候,我们就必须从链表头开始遍历查找。然而在标示链表头的时候确实有些麻烦,利用javascript的灵活性,我想我们还是很容易就解决的。从上图中我们也看到最后一个元素的引用应该设置为null。由于在链表中插入禾删除元素,只需要改变自身元素与相邻元素的引用就可以了,不必像数组那样移动元素的位置,这样看起来效率会高一点。
构建链表(construct linked list):
我们设计的这个链表是一个基于对象的链表,包括两个类:Node类用来表示节点,LinkedList类用来提供插入节点,删除节点,查询节点元素个数。。等一些列操作。
Node类:
function Node (element){
this.element = element;
this.next = null;
}
Node类包含两个属性,element用来保存节点的元素,next用来保存指向下一个节点的链接。head节点的next属性我们暂且设置为null,当有数据插入的时候我们在设置head的next属性指向这个新元素。
LinkedList类:
LinkedList类和Node类一样也是一个构造函数,但LinkListed类只有一个属性,那就是使用一个Node节点来保存该链表的头节点。
<html>
<head>
<title>Date Example</title>
</head>
<body>
<div id="content"></div>
<input type="button" value="Set InnerHTML" onclick="testDate()"> <script type="text/javascript"> // Node construct
function Node (element){
this.element = element;
this.next = null;
} // LinkedList construct
function LinkedList (){
this.head = new Node("head"); // 遍历链表查找给定的数据(我们要把数据插入到那个节点的后面)
this.find = function (item){
var currNode = this.head;
while (currNode.element != item){
currNode = currNode.next;
} return currNode
}; // 向链表中插入一个节点
this.insert = function (newElem, item){
var newNode = new Node(newElem);
var current = this.find(item);
newNode.next = current.next;
current.next = newNode;
}; // 查询前一个节点
this.findPrevious = function (item){
var currNode = this.head;
while ((currNode.next != null) && (currNode.next.element != item)){
currNode = currNode.next;
}
return currNode;
}; // 删除某个节点
this.remove = function (item){
var prevNode = this.findPrevious(item);
if (prevNode.next != null){ prevNode.next = prevNode.next.next;
}
}; // 显示列表中的节点
this.display = function (){
var currNode = this.head;
while (currNode.next != null){
console.log("current Node is:" + currNode.next.element);
currNode = currNode.next;
}
}; }
</script>
</body>
</html>
上面就是一个比较构造一个普通链表的方式。里面包含了基本的链表操作方法。
var cities = new LinkedList();
cities.insert("shang", "head");
cities.insert("hai", "shang");
cities.insert("shan", "hai");
cities.insert("xi", "shan");
cities.display();
在浏览器的Cnsole中查看结果。
链表在日常 使用中还有双向链表,循环链表。。。
首先来看一下双向链表吧:
在上面创建的链表中我们只能从链表的头遍历到链表的尾,二双向链表让我们既能从链表的头遍历到尾,也能让我们从尾遍历到头。其实很简单,我们在每个节点中增加一个属性,这个属性指向前驱节点的链接,这样只是给插入与删除节点多添加一些代码罢了。如图:

展示了双向链表的工作原理。
<html>
<head>
<title>Date Example</title>
</head>
<body>
<div id="content"></div>
<input type="button" value="Set InnerHTML" onclick="testDate()"> <script type="text/javascript"> // Node construct
function Node (element){
this.element = element;
this.next = null;
this.previous = null; } // LinkedList construct
function LinkedList (){
this.head = new Node("head"); // 遍历链表查找给定的数据(我们要把数据插入到那个节点的后面)
this.find = function (item){
var currNode = this.head;
while (currNode.element != item){
currNode = currNode.next;
} return currNode
}; // 向链表中插入一个节点
this.insert = function (newElem, item){
var newNode = new Node(newElem);
var current = this.find(item);
newNode.next = current.next;
newNode.previous = current;
current.next = newNode;
}; // 查找最后一个节点(便于我们从后往前遍历)
this.findLast = function (){
var lastNode = this.head;
while (lastNode.next != null){
lastNode = lastNode.next;
} return lastNode;
}; // 反序显示双向列表中的元素
this.displayReverse = function (){
var currNode = this.head;
currNode = this.findLast();
while (currNode.previous != null){
console.log("current Node is:" + currNode);
currNode = currNode.previous;
}
}; // 删除某个节点
this.remove = function (item){
var crrNode = this.find(item);
if (crrNode.next != null){ currNode.previous.next = currNode.next;
currNode.next.previous = currNode.preious;
currNode.previous = null;
currNode.next = null;
}
}; // 显示列表中的节点
this.display = function (){
var currNode = this.head;
while (currNode.next != null){
console.log("current Node is:" + currNode.next.element);
currNode = currNode.next;
}
}; } var cities = new LinkedList();
cities.insert("shang", "head");
cities.insert("hai", "shang");
cities.insert("shan", "hai");
cities.insert("xi", "shan");
cities.display(); </script>
</body>
</html>
循环列表:
循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的引用指向头节点,整个链表形成一个环

从链表的尾部向后移动,将会从新遍历这个链表。
<html>
<head>
<title>Date Example</title>
</head>
<body>
<div id="content"></div>
<input type="button" value="Set InnerHTML" onclick="testDate()"> <script type="text/javascript"> // Node construct
function Node (element){
this.element = element;
this.next = null;
} // LinkedList construct
function LinkedList (){
this.head = new Node("head");
this.head.next = this.head; // 遍历链表查找给定的数据(我们要把数据插入到那个节点的后面)
this.find = function (item){
var currNode = this.head;
while ((currNode.element != item) && (currNode.next.element != "head")){
currNode = currNode.next;
} return currNode
}; // 向链表中插入一个节点
this.insert = function (newElem, item){
var newNode = new Node(newElem);
var current = this.find(item);
newNode.next = current.next;
current.next = newNode;
}; // 查询前一个节点
this.findPrevious = function (item){
var currNode = this.head;
while ((currNode.next != null) && (currNode.next.element != item) && (currNode.next.element != "head")){
currNode = currNode.next;
}
return currNode;
}; // 删除某个节点
this.remove = function (item){
var prevNode = this.findPrevious(item);
if (prevNode.next != null){ prevNode.next = prevNode.next.next;
}
}; // 显示列表中的节点
this.display = function (){
var currNode = this.head;
while ((currNode.next != null) && (currNode.next.element != "head")){
console.log("current Node is:" + currNode.next.element);
currNode = currNode.next;
}
}; } var cities = new LinkedList();
cities.insert("shang", "head");
cities.insert("hai", "shang");
cities.insert("shan", "hai");
cities.insert("xi", "shan");
cities.display(); </script>
</body>
</html>
当我们在使用循环链表的时候,注意不要使程序陷入死循环。。。在以前这些方法的基础上我们还可以编写更多的方法,来简化我们的使用和操作。
javascript linkedlist data structures的更多相关文章
- javascript Set data structures
集合(set)是一组无序的,但彼此之间又有一定相关性的数据集.每个成员在数组中只能出现一次. 在使用集合(set)之前最好先理解一下内容: 1.不包含任何成员的集合称为空集合. 2.如果两个集合的成员 ...
- javascript Dictionary data structures
Dictionary常被称为数据字典,是一种用来保存键值对的数据结构,比如我们日常的电话本,就是一个Dictionary.我们通过键(名字),就可以访问到对应的值(电话号码).在C++与java中我们 ...
- JavaScript data types and data structures
JavaScript data types and data structures Programming languages all have built-in data structures, b ...
- [Javascript] Avoiding Mutations in JavaScript with Immutable Data Structures
To demonstrate the difference between mutability and immutability, imagine taking a drink from a gla ...
- The Swiss Army Knife of Data Structures … in C#
"I worked up a full implementation as well but I decided that it was too complicated to post in ...
- Go Data Structures: Interfaces
refer:http://research.swtch.com/interfaces Go Data Structures: Interfaces Posted on Tuesday, Decembe ...
- A library of generic data structures
A library of generic data structures including a list, array, hashtable, deque etc.. https://github. ...
- 剪短的python数据结构和算法的书《Data Structures and Algorithms Using Python》
按书上练习完,就可以知道日常的用处啦 #!/usr/bin/env python # -*- coding: utf-8 -*- # learn <<Problem Solving wit ...
- Persistent Data Structures
原文链接:http://www.codeproject.com/Articles/9680/Persistent-Data-Structures Introduction When you hear ...
随机推荐
- 升级mojave后的小问题解决
首先是xcode没了,我到苹果软件市场上重新下载了一个,可以了. 然后是virtualbox无法打开了,现实版本不兼容,我到官网重新下载了一个最新的6.0.然后就可以正常打开了,并且是无感升级,原来的 ...
- (转)机器学习的数学基础(1)--Dirichlet分布
转http://blog.csdn.net/jwh_bupt/article/details/8841644 这一系列(机器学习的数学基础)主要包括目前学习过程中回过头复习的基础数学知识的总结. 基础 ...
- js正则表达式/replace替换变量方法
转自:http://www.blogjava.net/pingpang/archive/2012/08/12/385342.html 1. javascript 正则对象替换创建和用法:/patter ...
- 【已解决】Python脚本运行出现语法错误:IndentationError: unindent does not match any outer indentation level
转自:http://www.crifan.com/python_syntax_error_indentationerror/comment-page-1/ [问题] 一个python脚本,本来都运行好 ...
- (数据挖掘-入门-3)基于用户的协同过滤之k近邻
主要内容: 1.k近邻 2.python实现 1.什么是k近邻(KNN) 在入门-1中,简单地实现了基于用户协同过滤的最近邻算法,所谓最近邻,就是找到距离最近或最相似的用户,将他的物品推荐出来. 而这 ...
- 火狐浏览器Firefox如何使用插件,火狐有哪些好用的插件
1 CoorPreviews 不打开网页链接预览该网页的内容. 预览如图所示: 点击关闭旁边的钉子可以让该窗口保持开着并且浏览速度加快.这对于快速浏览图片时非常有用. 2 FoxTab 3D方式预览网 ...
- IIS 之 未能加载文件或程序集“IBM.Data.DB2”或它的某一个依赖项。试图加载格式不正确的程序。
问题如下图所示: 原因分析:操作系统是64位的,但发布的程序引用了一些32位的ddl,所以出现了兼容性的问题. 解决方案:IIS → 应用程序池 → 对应的程序池 → 高级设置 → 启用32位应用程序 ...
- 绕过Web授权和认证之篡改HTTP请求
一.什么是HTTP请求 超文本传输协议(HTTP)提供了多种请求方法来与web服务器沟通.当然,大多数方法的初衷是帮助开发者在开发或调试过程中部署和测试HTTP应用.如果服务器配置不当,这些请求方法可 ...
- shell中如何取括号中的字符
1. 使用grep(结果带括号,不知道有没有办法仅把括号中的内容匹配出来) $a='abc[edg]adfirpqu' $echo $a|grep -o '\[.*\]' #中括号的处理需要转义 [e ...
- ubuntu 下安装摄像头驱动
sudo apt-get install cheese sudo apt-get install camorama 然后可以打开应用cheese,观察可以得到图像. 也可以通过代码获取图像.pytho ...