JavaScript数据结构之双向链表和双向循环链表的实现

双向链表和普通链表的区别在于,在链表中,一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素,另一个链向前一个元素。

双向链表提供了两种迭代列表的方法:从头到尾,或者反过来。我们也可以访问一个特定节点的下一个或前一个元素。在单向链表中,如果迭代列表时错过了要找的元素,就需要回到列表起点,重新开始迭代。这是双向链表的一个优点。

双向链表:单向链表只能向着一个方向遍历链表节点,而在节点指针域中增加了前向指针的双向链表,则可以向着两个方向遍历节点。这使得双向链表也可以在任何一个节点遍历整个链表。

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

  var length = 0,
    head = null,
    tail = null; 

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

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

      node.next = current;
      current.prev = node;
      previous.next = node;
      node.prev = previous;
    } 

    length++;
    return true;
  } 

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

      if(position === 0){ 

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

      }else if (position === length -1){
        current = tail;
        current.next = node;
        node.prev = current;
      }else {
        while(index++ < position){
          previous = current;
          current = current.next;
        }
        node.next = current;
        previous.next = node;
        current.prev = node;
        node.prev = previous;
      } 

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

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

      if (position === 0) {
        head = current.next; 

        if(length === 1){
          tail = null;
        }else{
          head.prev = null;
        }
      }else if(position === length - 1){
        current = tail;
        tail = current.prev;
        tail.next = null;
      } else{
        while(index++ < position){
          previous = current;
          current = current.next;
        } 

        previous.next = current.next;
        current.next.prev = previous;
      };
      length-- ; 

      return current.element;
    }else{
      return false;
    }
  }; 

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

    if(current.element === element){
      head = current.next;
    }
    previous = current;
    current = current.next; 

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

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

    var current = head,
      previous; 

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

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

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

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

    while(current && index++ < length){
      if (current.element === element) {
        return 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;
  }; 

  this.getTail = function(){
    return tail;
  };
}

双向循环链表:将双向链表的头尾指针相连,就构成了双向循环链表。这种链表从任意一个节点都可以同时向两个方向进行节点遍历,查询节点的速度也是最快的。

/*双向循环链表*/
function DoublyCircularLinkedList(){
  var Node = function(element){
    this.element = element;
    this.next = null;
    this.prev = null;
  }; 

  var length = 0,
    head = null,
    tail = null; 

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

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

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

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

    length++;
    return true;
  }; 

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

      if(position === 0){ 

        if(!head){ 

          node.next = node;
          node.tail = node;
          head = node;
          tail = node; 

        }else{ 

          current.prev = node;
          node.next = current;
          head = node;
          node.prev = tail; 

        } 

      }else if(position === length){
        current = tail; 

        current.next = node;
        node.prev = current;
        tail = node;
        node.next = head;
      }else{ 

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

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

      } 

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

  this.removeAt = function(position){
    if(position > -1 && position < length){ 

      var current = head,
        index = 0,
        previous; 

      if(position === 0){ 

        current.next.previous = tail;
        head = current.next; 

      }else if(position === length - 1){ 

        current = tail; 

        current.prev.next = head;
        head.prev = current.prev;
        tail = current.prev;
      }else{ 

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

        previous.next = current.next;
        current.next.prev = previous; 

      } 

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

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

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

      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;
      tail = null;
      length--;
      return current.element;
    } 

    while(indexCheck++ < length){
      previous = current;
      current = current.next;
    } 

    previous.next = head;
    tail = previous.next;
    length--;
    return current.element;
  }; 

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

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

    return false;
  }; 

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

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

    return string;
  }; 

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

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

  this.getTail = function(){
    return tail;
  }; 

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

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

(0)

相关推荐

  • js实现双向链表互联网机顶盒实战应用实现

    上实战代码: linkedlistnode.js 节点类 复制代码 代码如下: /* * 链表节点 */ Dare.LinkedListNode = function () { this.data = null;//数据域 this.prev = null;//前驱 this.next = null;//后驱 }; Dare.extend(Dare.LinkedListNode, Dare); Dare.LinkedListNode.prototype.getValue = function (

  • JavaScript数据结构之双向链表定义与使用方法示例

    本文实例讲述了JavaScript数据结构之双向链表定义与使用方法.分享给大家供大家参考,具体如下: 双向链表和普通链表的区别在于,在链表中,一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素,另一个链向前一个元素. 双向链表提供了两种迭代列表的方法:从头到尾,或者反过来.我们也可以访问一个特定节点的下一个或前一个元素.在单向链表中,如果迭代列表时错过了要找的元素,就需要回到列表起点,重新开始迭代.这是双向链表的一个优点. function DoubleLink(

  • JavaScript数据结构之双向链表和双向循环链表的实现

    双向链表和普通链表的区别在于,在链表中,一个节点只有链向下一个节点的链接,而在双向链表中,链接是双向的:一个链向下一个元素,另一个链向前一个元素. 双向链表提供了两种迭代列表的方法:从头到尾,或者反过来.我们也可以访问一个特定节点的下一个或前一个元素.在单向链表中,如果迭代列表时错过了要找的元素,就需要回到列表起点,重新开始迭代.这是双向链表的一个优点. 双向链表:单向链表只能向着一个方向遍历链表节点,而在节点指针域中增加了前向指针的双向链表,则可以向着两个方向遍历节点.这使得双向链表也可以在任

  • C语言中双向链表和双向循环链表详解

    双向链表和双向循环链表 和单向链表相比,多了一个前驱结点.如果他为空,那么next和prior都指向自己.而对于双循环链表,只需要最后一个元素的next指向head->next,head->next的prior指向最后一个节点即可. 插入操作 新节点s插入链表,s->next给p结点,s->prior给p->prior,然后,p->prior->next指向s,p->prior再指向s.顺序需要注意 s->next = p; s->prior =

  • JavaScript数据结构之双向链表

    单向链表在遍历时只能从头到尾或者从尾遍历到头:所以单向链表可以轻松到达下一节点,但是回到上一个节点是很困难的 而双向链表既可以从头遍历到尾, 又可以从尾遍历到头,链表的相联是双向的,一个节点既有向前连接的引用,也有向后连接的引用 但是正因如此,双向链表在插入或者删除某个节点时,需要处理四个节点的引用,并且所占用内存空间也更大一些 双向链表实现 JavaScript 代码实现双向链表 // 创建双向链表的构造函数 function DoublyLinkedList() { // 创建节点构造函数

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

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

  • C++零基础精通数据结构之带头双向循环链表

    目录 与单链表的区别 代码的实现 接口 节点的构造 初始化链表 开辟节点 销毁链表 打印链表 尾插链表 尾删链表 头插链表 头删链表 查找链表 链表pos位置的删除 总结 与单链表的区别 单向/双向 单向:只有一个next指针,只指向下一位元素 双向:有两个指针,指向上一位和下一位元素,寻找前一节点和后一节点很便利 带头/不带头 带头:在本来的头结点之前还有一个哨兵卫节点作为头节点,它的址域指针指向头节点,值域不做使用 不带头:没有哨兵卫头节点,在尾删尾插等问题中要考虑头结点的情况(局限) 循环

  • C语言编程数据结构带头双向循环链表全面详解

    目录 前言 一.什么是带头循环双向链表 二.链表初始化 三.链表接口函数 1.尾插 2.头插 3.头删 4.尾删 5.任意位置插入数据 6.任意位置删除数据 四.打印链表 总结 前言 上一篇数据结构专栏:C语言数据结构单链表接口函数全面讲解教程 我们介绍了单链表的各个接口函数,大家可能会发现单链表存在一些缺陷:比如它一个节点要存储数据+下一个节点地址,占用的空间要远多于顺序表:并且由于单链表是无法从后往前找的,如果你想进行尾删这样的操作,你必须从第一个节点往后找,你的时间复杂度一定是O(n).

  • C语言数据结构之双向循环链表的实例

    数据结构之双向循环链表 实例代码: #include <stdlib.h> #include <stdio.h> #include <malloc.h> typedef struct Node{ struct Node *pNext; int data; struct Node *prior; } NODE,*PNODE; PNODE CreatList(); void TreNode(PNODE pHead); bool isEmpty(PNODE pHead); i

  • C语言带头双向循环链表的示例代码

    目录 前言 结构分析 链表的基本操作实现 创建节点 初始化链表 链表销毁 打印链表 链表尾插 链表尾删 链表头插 链表头删 链表查找 链表pos位置前面去插入 删除pos位置 链表判空 代码复用 总代码及头文件 前言 对于链表来说,不只有单链表这一个品种: 链表有很多种形态 按方向分:单向.双向 按带不带头:带头.不带头 按循环:循环.不循环 1.单向或则双向: 2.带头或者不带头: 3.循环或者不循环: 组合排列一下的话,链表一共有8种形态!!! 今天我们就来学习一下结构最复杂的带头双向循环链

  • JavaScript数据结构链表知识详解

    最近在看<javascript数据结构和算法>这本书,补一下数据结构和算法部分的知识,觉得自己这块是短板. 链表:存储有序的元素集合,但不同于数组,链表中的元素在内存中不是连续放置的.每个元素由一个存储元素本身的节点和一个指向下一个元素的引用(也称指针或链接)组成. 好处:可以添加或移除任意项,它会按需扩容,且不需要移动其他元素. 与数组的区别: 数组:可以直接访问任何位置的任何元素: 链表:想要访问链表中的一个元素,需要从起点(表头)开始迭代列表直到找到所需的元素. 做点小笔记. funct

随机推荐