博客
关于我
JS数据结构--双向链表--常见操作
阅读量:333 次
发布时间:2019-03-04

本文共 4766 字,大约阅读时间需要 15 分钟。

双向链表的优势与实现

单向链表的局限性

在单向链表中,虽然可以轻松从头到尾遍历,但回到前一个节点却非常困难。这使得单向链表难以支持复杂的操作,如插入删除等。

双向链表的优势

双向链表通过引入前驱和后驱指针,既可以从头到尾遍历,也能从尾到头遍历。这种双向连接方式有效解决了单向链表的局限性。

双向链表的特点

双向链表的每个节点包含三个部分:前驱指针(prev)、节点数据(item)和后驱指针(next)。链表的首节点的前驱指针为null,末节点的后驱指针为null。

双向链表的实现

function DoublyLinkedList() {    // 内部类:节点类    function Node(data) {        this.data = data;        this.prev = null;        this.next = null;    }    // 属性    this.head = null;    this.tail = null;    this.length = 0;}

双向链表的基本操作

  • append方法:在链表尾部插入节点
  • DoublyLinkedList.prototype.append = function(data) {    var newNode = new Node(data);    if (this.length === 0) {        this.head = newNode;    } else {        var current = this.head;        while (current.next) {            current = current.next;        }        current.next = newNode;    }    this.length += 1;};
    1. 链表转换成字符串:forwardString方法和backwardString方法
    2. // forwardString方法DoublyLinkedList.prototype.forwardString = function() {    var current = this.head;    var resultString = '';    while (current) {        resultString += current.data + '';        current = current.prev;    }    return resultString;};// backwardString方法DoublyLinkedList.prototype.backwardString = function() {    var current = this.head;    var resultString = '';    while (current) {        resultString += current.data + '';        current = current.next;    }    return resultString;};

      双向链表的高级操作

    3. 插入方法:按位置插入节点
    4. DoublyLinkedList.prototype.insert = function(position, data) {    // 越界判断    if (position < 0 || position > this.length) return false;    var newNode = new Node(data);    if (this.length === 0) {        this.head = newNode;        this.tail = newNode;    } else {        if (position === 0) {            newNode.next = this.head;            this.head.prev = newNode;            this.head = newNode;        } else if (position === this.length) {            this.tail.next = newNode;            newNode.prev = this.tail;            this.tail = newNode;        } else {            var current = this.head;            var index = 0;            while (index++ < position) {                current = current.next;            }            newNode.next = current;            newNode.prev = current.prev;            current.prev.next = newNode;            current.prev = newNode;        }    }    this.length += 1;    return true;};
      1. 获取方法:获取指定位置的数据
      2. // 方法1(普通方法)DoublyLinkedList.prototype.get = function(position) {    if (position < 0 || position >= this.length) return false;    var current = this.head;    var index = 0;    while (index++ < position) {        current = current.next;    }    return current.data;};// 方法2DoublyLinkedList.prototype.get = function(position) {    var current = this.tail;    var index = this.length - 1;    while (index-- > position) {        current = current.prev;    }    return current.data;};
        1. 查找方法:返回元素在链表中的索引
        2. DoublyLinkedList.prototype.indexOf = function(data) {    var current = this.head;    var index = 0;    while (current) {        if (current.data === data) {            return index;        } else {            current = current.next;            index++;        }    }    return -1;};
          1. 更新方法:修改数据元素
          2. DoublyLinkedList.prototype.update = function(position, newData) {    if (position < 0 || position >= this.length) return false;    var current = this.head;    var index = 0;    while (index++ < position) {        current = current.next;    }    current.data = newData;    return true;};
            1. 删除方法:删除链表中的节点
            2. DoublyLinkedList.prototype.removeAt = function(position) {    if (position < 0 || position >= this.length) return null;    var current = this.head;    if (this.length === 1) {        this.head = null;        this.tail = null;    } else {        if (position === 0) {            this.head.next.prev = null;            this.head = this.head.next;        } else if (position === this.length - 1) {            current = this.tail;            this.tail.prev.next = null;            this.tail = this.tail.prev;        } else {            var index = 0;            while (index++ < position) {                current = current.next;            }            current.prev.next = current.next;            current.next.prev = current.prev;        }    }    this.length -= 1;    return current.data;};
              1. 删除方法:根据具体数据删除链表中的节点
              2. DoublyLinkedList.prototype.remove = function(data) {    var index = this.indexOf(data);    return this.removeAt(index);};
                1. 判断是否为空
                2. DoublyLinkedList.prototype.isEmpty = function() {    return this.length === 0;};
                  1. 获取链表长度
                  2. DoublyLinkedList.prototype.size = function() {    return this.length;};
                    1. 获取链表首节点数据
                    2. DoublyLinkedList.prototype.getHead = function() {    return this.head.data;};
                      1. 获取链表末节点数据
                      2. DoublyLinkedList.prototype.getTail = function() {    return this.tail.data;};

                        总结

                        双向链表通过引入前驱和后驱指针,显著提升了链表的灵活性和操作能力。相比单向链表,双向链表能够支持双向遍历,但在实现和内存占用上也存在一定的挑战。

    转载地址:http://ohze.baihongyu.com/

    你可能感兴趣的文章
    OpenEuler23.03欧拉系统_安装瀚高数据库企业版6.0.4_踩坑_安装以后系统无法联网_启动ens33网卡---国产瀚高数据库工作笔记002
    查看>>
    OpenFeign 入门与实战
    查看>>
    OpenFeign源码学习
    查看>>
    OpenFeign的使用方式成功解锁
    查看>>
    OpenFeign组件声明式服务调用
    查看>>
    openfeign远程调用不起作用解决_使用Spring Boot的spring.factories进行注入---SpringCloud Alibaba_若依微服务框架改造---工作笔记007
    查看>>
    openfire开发(四)消息拦截器
    查看>>
    openfire源码解读之将cache和session对象移入redis以提升性能
    查看>>
    Openfire身份认证绕过漏洞复现+利用(CVE-2023-32315)
    查看>>
    OpenForest 开源项目安装与使用指南
    查看>>
    OpenGL glBlendFunc() 设置颜色混合 透明度叠加计算
    查看>>
    OpenGL 中“立即模式”是什么意思?
    查看>>
    opengl 教程(15) 摄像机控制(2)
    查看>>
    opengl 深度详解,多重采样时,如何在OpenGL纹理中解析深度值?
    查看>>
    OpenGL 的内置矩阵种种
    查看>>
    OpenGL/OpenGL ES 入门:基础变换 - 初识向量/矩阵
    查看>>
    OpenGL中shader读取实现
    查看>>
    OpenGL中旋转平移缩放等变换的顺序对模型的影响
    查看>>
    Opengl中的gluProject函数认识
    查看>>
    OpenGl介绍
    查看>>