博客
关于我
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/

    你可能感兴趣的文章
    Nginx - 反向代理、负载均衡、动静分离、底层原理(案例实战分析)
    查看>>
    nginx 1.24.0 安装nginx最新稳定版
    查看>>
    nginx 301 永久重定向
    查看>>
    nginx css,js合并插件,淘宝nginx合并js,css插件
    查看>>
    Nginx gateway集群和动态网关
    查看>>
    Nginx Location配置总结
    查看>>
    Nginx log文件写入失败?log文件权限设置问题
    查看>>
    Nginx Lua install
    查看>>
    nginx net::ERR_ABORTED 403 (Forbidden)
    查看>>
    Nginx SSL私有证书自签,且反代80端口
    查看>>
    Nginx upstream性能优化
    查看>>
    Nginx 中解决跨域问题
    查看>>
    nginx 代理解决跨域
    查看>>
    Nginx 动静分离与负载均衡的实现
    查看>>
    Nginx 反向代理 MinIO 及 ruoyi-vue-pro 配置 MinIO 详解
    查看>>
    nginx 反向代理 转发请求时,有时好有时没反应,产生原因及解决
    查看>>
    Nginx 反向代理解决跨域问题
    查看>>
    Nginx 反向代理配置去除前缀
    查看>>
    nginx 后端获取真实ip
    查看>>
    Nginx 多端口配置和访问异常问题的排查与优化
    查看>>