博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JavaScript的数据结构与算法(四) —— 双向链表
阅读量:6685 次
发布时间:2019-06-25

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

链表

链表存储有序的元素集合,但不同于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本事的节点和一个指向下一个元素的引用组成。相对于传统的数组,链表的一个好处在于,添加或者删除元素的时候不需要移动其他元素。 使用链表结构可以克服数组需要预先知道数据大小的缺点(C语言的数组需要预先定义长度),链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。

数组和链表的一个不同在于数组可以直接访问任何位置的元素,而想要访问链表中的一个元素,需要从起点开始迭代列表。

链表又包括:单向链表 和 双向链表;

双向链表

双向链表与单向链表很是相像。在单向链表中,只有指向下一个节点的链接。但在双向链表中,还有指向上一个节点的链接,是双向的。


让我们来简单实现一个双向链表类,并包含如下功能:

  • append(element): 添加元素到链表尾部
  • insert(position,element): 向双向链表中某个位置插入元素
  • removeAt(position): 移除双向链表中某个位置的元素
  • getHead(): 获取双向链表的头部
  • getTail(): 获取双向链表的尾部
  • isEmpty(): 检查双向链表是否为空,为空则返回true
  • size(): 返回双向链表长度

代码如下:

function DoublyLinkedList() {    /**     * 双向链表中节点的构造函数     *      * @param {any} element 要插入链表的元素     */    var Node = function (element) {        this.element = element;        this.next = null;        this.prev = null;    }    // 双向链表的长度    var length = 0;    // 双向链表的头结点,默认为null    var head = null;    // 双向链表的尾结点,默认为null    var tail = null;        /**     * 添加元素到双向链表的尾部     *      * @param {any} element 要插入的元素     */    this.append = function (element) {        var node = new Node(element),            current = head;        if (head === null) {            head = node            tail = node        } else {            while (current.next) {                current = current.next;            }            current.next = node;            node.prev = current;            tail = node;        }        length++;        return true;    }    /**     * 向双向链表中某个位置插入元素     *      * @param {any} position 要插入的位置     * @param {any} element 要插入的元素     * @returns 插入成功或失败     */    this.insert = function (position, element) {        var node = new Node(element),            current = head,            previous,            index = 0;        // 限制边界        if (position < 0 && position >= length) {            return false;        }        if (position === 0) {            // 在链表的头部插入元素            node.next = head            head.prev = node            head = node        } else if (position === length) {            // 在链表的尾部插入元素            current = tail;            current.next = node;            node.prev = current;            tail = node;        } else {            // 在链表的中间插入元素            while (index++ < position) {                previous = current                current = current.next;            }            // 绑定前一个节点和插入节点的关系            previous.next = node;            node.prev = previous;            // 绑定后一个节点和插入节点的关系            node.next = current;            current.prev = node;        }        length++;        return true;    }    /**     * 移除双向链表中某个位置的元素     *      * @param {any} position 要移除元素的位置     * @returns 移除成功,返回移除的元素     */    this.removeAt = function (position) {        var previous,            current = head,            index = 0;         // 限制边界         if (position < 0 && position >= length) {            return false;        }        if (position === 0) {            // 移除链表的头部            head = current.next;            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;    }    this.getHead = function () {        return head.element;    }    this.isEmpty = function () {        return length === 0    }    this.getTail = function () {                return tail.element;    }    this.size = function () {        return length    }}复制代码

转载于:https://juejin.im/post/5bfd03c86fb9a049e93c6b2c

你可能感兴趣的文章
三层交换机与路由器的相关配置
查看>>
html表单笔记
查看>>
我的友情链接
查看>>
nginx负载均衡的5种策略
查看>>
MyBatis学习总结(三)——优化MyBatis配置文件中的配置
查看>>
翻译软件开发(do it yourself)
查看>>
《Java程序员的基本修养》读书笔记之内存回收
查看>>
鸟哥私房菜重温6
查看>>
适用于ASP等环境的JS日期选择控件
查看>>
nomad安装
查看>>
MySQL主备复制数据不一致的情况
查看>>
CU3ER非常Cool的3D效果的Flash Slider
查看>>
中财讯 爆遍历目录漏洞
查看>>
MongoDB 数据库备份脚本
查看>>
Linux常用命令
查看>>
10、《每天5分钟玩转Docker容器技术》学习-Docker命令之本地镜像管理
查看>>
shell脚本:输出昨天的日期
查看>>
css优先级详解
查看>>
小白第三天
查看>>
2016年linux运维人员必会开源运维工具体系
查看>>