JavaScript数据结构之单链表和循环链表

数据结构系列前言:

数据结构作为程序员的基本知识,需要我们每个人牢牢掌握。近期我也展开了对数据结构的二次学习,来弥补当年挖的坑。。。。。。   当时上课的时候也就是跟着听课,没有亲自实现任何一种数据结构,更别提利用数据结构来解决问题了。  现在就来填坑了奋斗   在这里提醒看到我博客的孩子们,如果你还是在校生,永远不要轻视任何一门基础课的学习,这个时候挖的坑,要么需要用双倍的努力去填,要么会直接影响一个人的能力等等。。。。。。 千万别给自己挖坑

进入正题,关于链表的数据结构知识,这里简单介绍下:

链表是一种物理存储单元上非线性、非连续性的数据结构(它在数据逻辑上是线性的),它的每个节点由两个域组成:数据域和指针域。数据域中存储实际数据,指针域则存储着指针信息,指向链表中的下一个元素或者上一个元素。正是由于指针的存在,链表的存储在物理单元是非连续性的。

链表的优点和缺点同样明显。和线性表相比,链表在添加和删除节点上的效率更高,因为其只需要修改指针信息即可完成操作,而不像线性表(数组)那样需要移动元素。同样的,链表的长度在理论上也是无限的(在存储器容量范围内),并可以动态变化长度,相比线性表优势很大。 相应的,由于线性表无法随机访问节点,只能通过指针顺着链表进行遍历查询来访问,故其访问数据元素的效率比较低。

下面是JS部分

这里面封装了的常用方法及描述:

方法 描述
append(element)   向链表尾部添加结点element
insert(position,element)  向位置position处插入结点element
removeAt(position)  按照索引值position删除结点
remove(element)  搜索并删除给定结点element
remove()  删除链表中最后一个结点
indexOf(element) 查找并返回给定结点element的索引值
isEmpty()  判断链表是否为空
size()  获取链表长度
toString()  转换为字符串输出
getHead() 获取头结点
getTail()  获取尾结点

对于各常用方法的算法描述在这里就不写了,相信大家都可以轻易读懂并理解,毕竟都是非常基础的知识了。

单链表:

function LinkedList(){
 /*节点定义*/
 var Node = function(element){
  this.element = element; //存放节点内容
  this.next = null; //指针
 } 

 var length = 0, //存放链表长度
  head = null; //头指针 

 this.append = function(element){
  var node = new Node(element),
   current; //操作所用指针 

  if (!head){
   head = node;
  }else {
   current = head; 

   while(current.next){
    current = current.next;
   } 

   current.next = node;
  } 

  length++;
  return true;
 }; 

 this.insert = function(position, element){
  if (position >= 0 && position <= length) {
   var node = new Node(element),
    current = head,
    previous,
    index = 0; 

   if(position === 0){
    node.next = current;
    head = node;
   }else{
    while(index++ < position){
     previous = current;
     current = current.next;
    }
    node.next = current;
    previous.next = node;
   } 

   length++;
   return true;
  }else{
   return false;
  }
  }; 

 this.removeAt = function(position){
  if(position > -1 && position < length){
   var current = head,
    previous,
    index = 0; 

   if (position === 0) { 

    head = current.next; 

   }else{ 

    while (index++ < position){
     previous = current;
     current = current.next;
    } 

    previous.next = current.next;
   }; 

   length--;
   return current.element;
  }else{
   return null;
  }
 }; 

 this.remove = function(element){
  var current = head,
   previous; 

  if(element === current.element){
   head = current.next;
   length--;
   return true;
  }
  previous = current;
  current = current.next; 

  while(current){
   if(element === current.element){
    previous.next = current.next;
    length--;
    return true;
   }else{
    previous = current;
    current = current.next;
   }
  }
  return false;
 }; 

 this.remove = function(){
  if(length < 1){
   return false;
  } 

  var current = head,
  previous; 

  if(length == 1){
   head = null;
   length--;
   return current.element;
  } 

  while(current.next !== null){
   previous = current;
   current = current.next;
  } 

  previous.next = null;
  length--;
  return current.element;
 }; 

 this.indexOf = function(element){
  var current = head,
   index = 0; 

  while(current){
   if(element === current.element){
    return index;
   }
   index++;
   current = current.next;
  } 

  return false;
 }; 

 this.isEmpty = function(){
  return length === 0;
 }; 

 this.size = function(){
  return length;
 }; 

 this.toString = function(){
  var current = head,
   string = ''; 

  while(current){
   string += current.element;
   current = current.next;
  }
  return string;
 };  

 this.getHead = function(){
  return head;
 } 

}

循环链表:在单链表的基础上,将尾节点的指针指向头结点,就构成了一个循环链表。环形链表从任意一个节点开始,都可以遍历整个链表。

function CircularLinkedList(){
 var Node = function(element){
  this.element = element;
  this.next = null;
 } 

 var length = 0,
  head = null; 

 this.append = function(element){
  var node = new Node(element),
   current; 

  if (!head) {
   head = node;
   node.next = head;
  }else{
   current = head; 

   while(current.next !== head){
    current = current.next;
   } 

   current.next = node;
   node.next = head;
  }; 

  length++;
  return true;
 }; 

 this.insert = function(position, element){
  if(position > -1 && position < length){
   var node = new Node(element),
    index = 0,
    current = head,
    previous; 

   if (position === 0) { 

    node.next = head;
    head = node; 

   }else{ 

    while(index++ < position){
     previous = current;
     current = current.next;
    } 

    previous.next = node;
    node.next = current; 

   }; 

   length++;
   return true;
  }else{
   return false;
  }
 }; 

 this.removeAt = function(position){
  if(position > -1 && position < length){
   var current = head,
    previous,
    index = 0; 

   if (position === 0) { 

    head = current.next; 

   }else{ 

    while (index++ < position){
     previous = current;
     current = current.next;
    } 

    previous.next = current.next;
   }; 

   length--;
   return current.element;
  }else{
   return null;
  }
 }; 

 this.remove = function (element){
  var current = head,
   previous,
   indexCheck = 0; 

  while(current && indexCheck < length){
   if(current.element === element){
    if(indexCheck == 0){
     head = current.next;
     length--;
     return true;
    }else{
     previous.next = current.next;
     length--;
     return true;
    }
   }else{
    previous = current;
    current = current.next;
    indexCheck++;
   }
  }
  return false;
 }; 

 this.remove = function(){
  if(length === 0){
   return false;
  } 

  var current = head,
   previous,
   indexCheck = 0; 

  if(length === 1){
   head = null;
   length--;
   return current.element;
  } 

  while(indexCheck++ < length){
   previous = current;
   current = current.next;
  }
  previous.next = head;
  length--;
  return current.element;
 }; 

 this.indexOf = function(element){
  var current = head,
   index = 0; 

  while(current && index < length){
   if(current.element === element){
    return index;
   }else{
    index++;
    current = current.next;
   }
  }
  return false;
 }; 

 this.isEmpty = function(){
  return length === 0;
 }; 

 this.size = function(){
  return length;
 }; 

 this.toString = function(){
  var current = head,
   string = '',
   indexCheck = 0; 

  while(current && indexCheck < length){
   string += current.element;
   current = current.next;
   indexCheck++;
  } 

  return string;
 };  

}

使用方法:

在类外部扩充方法:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • javascript循环链表之约瑟夫环的实现方法

    前言 传说在公元1 世纪的犹太战争中,犹太历史学家弗拉维奥·约瑟夫斯和他的40 个同胞被罗马士兵包围.犹太士兵决定宁可自杀也不做俘虏,于是商量出了一个自杀方案.他们围成一个圈,从一个人开始,数到第三个人时将第三个人杀死,然后再数,直到杀光所有人.约瑟夫和另外一个人决定不参加这个疯狂的游戏,他们快速地计算出了两个位置,站在那里得以幸存.写一段程序将n 个人围成一圈,并且第m个人会被杀掉,计算一圈人中哪两个人最后会存活.使用循环链表解决该问题. 看到这个问题首先想到的是要用到循环链表,还有就是要计算

  • JavaScript数据结构之链表的实现

    前面楼主分别讨论了数据结构栈与队列的实现,当时所用的数据结构都是用的数组来进行实现,但是数组有的时候并不是最佳的数据结构,比如在数组中新增删除元素的时候需要将其他元素进行移动,而在javascript中使用spit()方法不需要访问其他元素.如果你在使用数组的时候发现很慢,就可以考虑使用链表. 链表的概念 链表是一种常见的数据结构.它是动态地进行存储分配的一种结构.链表有一个"头指针"变量,以head表示,它存放一个地址,指向一个元素.每个结点都使用一个对象的引用指标它的后继,指向另一

  • js单向链表的具体实现实例

    复制代码 代码如下: function linkNode(_key, _value){    /// <summary>    /// 链表类的节点类    /// </summary>    this.Key = _key;    this.Value = _value;    this.next = null;}function Link(){    /// <summary>    /// 创建一个链表类    /// </summary>    th

  • Node.js环境下JavaScript实现单链表与双链表结构

    单链表(LinkedList)的javascript实现 npmjs相关库: complex-list.smart-list.singly-linked-list 编程思路: add方法用于将元素追加到链表尾部,借由insert方法来实现: 注意各个函数的边界条件处理. 自己的实现: SingleNode.js (function(){ "use strict"; function Node(element){ this.element = element; this.next = n

  • javascript写的一个链表实现代码

    本来要用Array来保存数据的,没试过用JS来数据结构,就用JS来试试吧. JS效率真的很低一个链表装1000个对象浏览器就提示运行缓慢了. 之前觉得AJAX3D挺用前景的,现在看来还没有流行就要夭折了.用delphi开发的游戏人们都觉得太慢了,何况用JS. 下面是我实现的一个链表: 复制代码 代码如下: /*@author eric *@mail shmilyhe@163.com *blog.csdn.net/shmilyhe */ <script> function Student(no,

  • JavaScript实现的链表数据结构实例

    此例是javascript来建立链表.. 并对此进行了排序.. 还可以在GenericList一般链表上进行扩展. 实现各种排序及增,删,改结点.. 复制代码 代码如下: function Node(){   this.data=null;   this.next=null; } function GenericList(){   this.head=null;   this.current=null;   //打出所有的链表结点   this.print= function(){   this

  • JS使用单链表统计英语单词出现次数

    本文实例为大家分享了JS 列出所有单词及其出现次数的实现代码,JS统计英语单词出现次数,可以调用LinkedList 类的方法orderInsert(), 以字母大小的顺序储存 英文字符串,同时记录英文单词出现的次数,供大家参考,具体内容如下 <html> <head> <title>Linked List</title> <meta charset="utf-8"> </head> <body> &l

  • JavaScript数据结构之单链表和循环链表

    数据结构系列前言: 数据结构作为程序员的基本知识,需要我们每个人牢牢掌握.近期我也展开了对数据结构的二次学习,来弥补当年挖的坑......   当时上课的时候也就是跟着听课,没有亲自实现任何一种数据结构,更别提利用数据结构来解决问题了.  现在就来填坑了奋斗   在这里提醒看到我博客的孩子们,如果你还是在校生,永远不要轻视任何一门基础课的学习,这个时候挖的坑,要么需要用双倍的努力去填,要么会直接影响一个人的能力等等...... 千万别给自己挖坑 进入正题,关于链表的数据结构知识,这里简单介绍下:

  • javascript数据结构之双链表插入排序实例详解

    本文实例讲述了javascript数据结构之双链表插入排序实现方法.分享给大家供大家参考,具体如下: 数组存储前提下,插入排序算法,在最坏情况下,前面的元素需要不断向后移,以便在插入点留出空位,让目标元素插入. 换成链表时,显然无需做这种大量移动,根据每个节点的前驱节点"指针",向前找到插入点后,直接把目标值从原链表上摘下,然后在插入点把链表断成二截,然后跟目标点重新接起来即可. <!doctype html> <html> <head> <t

  • python算法与数据结构之单链表的实现代码

    =一.链表 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成.每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域. 相比于线性表顺序结构,操作复杂.由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是

  • C++数据结构之单链表

    目录 单链表结构的定义 单链表打印 动态申请一个结点 单链表尾插 单链表尾删 单链表头插 单链表头删 求单链表长度 单链表查找 单链表在pos位置插入 单链表在pos后面位置插入 单链表删除pos位置 单链表删除pos的下一个结点 判断单链表是否为空 头文件 源文件 简介: 线性表的顺序存储结构有一个缺点就是插入和删除时需要移动大量元素,这会耗费许多时间.能不能想办法解决呢?干脆所有的元素都不要考虑相邻位置了,哪有空位就到哪里,让每一个元素都知道它下一个元素的位置在哪里.线性表链式存储结构: 用

  • C#数据结构之单链表(LinkList)实例详解

    本文实例讲述了C#数据结构之单链表(LinkList)实现方法.分享给大家供大家参考,具体如下: 这里我们来看下"单链表(LinkList)".在上一篇<C#数据结构之顺序表(SeqList)实例详解>的最后,我们指出了:顺序表要求开辟一组连续的内存空间,而且插入/删除元素时,为了保证元素的顺序性,必须对后面的元素进行移动.如果你的应用中需要频繁对元素进行插入/删除,那么开销会很大. 而链表结构正好相反,先来看下结构: 每个元素至少具有二个属性:data和next.data

  • Python数据结构之单链表详解

    本文实例为大家分享了Python数据结构之单链表的具体代码,供大家参考,具体内容如下 # 节点类 class Node(): __slots__=['_item','_next'] # 限定Node实例的属性 def __init__(self,item): self._item = item self._next = None # Node的指针部分默认指向None def getItem(self): return self._item def getNext(self): return s

  • Java数据结构之单链表详解

    一.图示 二.链表的概念及结构 链表是一种物理存储结构上非连续存储结构,数据元素的逻辑顺序是通过链表中的引用链接次序实现的 . 实际中链表的结构非常多样,以下情况组合起来就有8种链表结构: 单向.双向 带头.不带头 循环.非循环 今天,我们实现的是一个 单向 无头 非循环的链表. 下面是此链表的结构组成. 三.单链表的实现 (1)定义一个节点类型 我们创建一个 ListNode 的类作为节点类型,那么我们如何定义成员属性呢? 通过上面的结构分析,我们需要定义两个成员变量 val --作为该节点的

  • C++数据结构之单链表的实现

    目录 一.单链表的定义 二.单链表的基本操作的实现 1.初始化 2.取值 3.查找 4.插入 5.删除 三.完整代码 四.测试一下代码 一.单链表的定义 线性表的链式存储又称为单链表,它是指通过一组任意的存储单元来存储线性表中的数据元素.为了建立数据元素之间的线性关系,对每个链表结点,除存放元素自身的信息外,还需要存放一个指向其后继的指针. 单链表中结点类型的描述如下: typedef struct LNode{ // 定义单链表节点类型 ElemType data; // 数据域 struct

  • C语言数据结构之单链表的实现

    目录 一.为什么使用链表 二.链表的概念 三.链表的实现 3.1 创建链表前须知 3.2 定义结构体 3.3 申请一个节点 3.4 链表的头插 3.5 链表的尾插 3.6 链表的尾删 3.7 链表的头删 3.8 寻找某节点 3.9 在指定节点前插入节点 3.10 删除指定节点前的节点 3.11 链表的销毁 一.为什么使用链表 在学习链表以前,我们存储数据用的方式就是数组.使用数组的好处就是便于查找数据,但缺点也很明显. 使用前需声明数组的长度,一旦声明长度就不能更改 插入和删除操作需要移动大量的

  • C语言数据结构之单链表与双链表的增删改查操作实现

    目录 前言 单链表的增删改查 定义结构体以及初始化 增加结点 删除结点 查找修改结点 移除结点 最终效果 双链表的基本操作 初始化建表 遍历双链表 指定位置插入结点 指定位置删除结点 查找结点位置 最终效果 结语 前言 上篇博客分享了创建链表传入二级指针的细节,那么今天就分享几个c语言课程实践设计吧.这些程序设计搞懂了的话相当于链表的基础知识牢牢掌握了,那么再应对复杂的链表类的题也就能慢慢钻研了.学习是一个积累的过程,想要游刃有余就得勤学苦练! 单链表的增删改查 (1)项目需求 构造带有头结点的

随机推荐