数据结构——链表

单链表

线性表的链式存储,包含两个域,一个存储的值(this.data),一个指向下一个链表节点(this.next)。

封装链表类,添加链表的属性:链表节点、头部(链表的起始点)、长度。

// 封装链表类
    function LinkedList() {
        // 内部的类:节点类
        function Node(data) {
            this.data = data;
            this.next = null;
        }
        //指向链表头部的属性
        this.head = null
        //记录链表长度的属性
        this.length = 0; 
    }

给链表添加方法进行增删改查等操作。

1.添加节点append
LinkedList.prototype.append = function(data) {
            //1.创建新节点
            var newNode = new Node(data);

            //2.判断是否存在第一个节点
                //2.1 不存在第一个节点
            if(this.length == 0) {
                this.head = newNode;
            } else {
                // 2.2 存在第一个节点,找到最后一个节点赋值
                // current即为链表的指针
                var current = this.head;
                while(current.next) {
                    current = current.next;
                }
                // 最后节点的next指向新节点
                current.next = newNode;
            }
            // 长度属性加一
            this.length += 1;
        }
2.tostring()
       LinkedList.prototype.toString = function() {
            // 指针current,存储结果tostring
            var current = this.head;
            var listString = '';
            // 遍历链表
            while(current) {
                listString += current.data + ' ';
                current = current.next;
            }
            return listString;
        }
3.在确定位置position插入节点
       LinkedList.prototype.insert = function(position, data) {
            //1.判断是否超出本身链表长度 或 小于0
            if(position < 0 || position > this.length) return false;
            //2.创建新插入节点
            var newNode = new Node(data);
            //3.插入数据
                //3.1 插入位置为第一个
            if(position == 0) {
            	// 修改头部指针
                newNode.next = this.head;
                this.head = newNode;
                //3.2 插入中间位置
            } else {
                var index = 0;
                var current = this.head;
                var previous = null;
                // 查找对应位置节点
                while(index++ < position) {
                    previous = current;
                    current = current.next;
                }
                // 插入节点,修改指向
                newNode.next = current;
                previous.next = newNode;
            }
            //4.增加长度
            this.length += 1;
            return true;
        }
4.查找某个位置(position)的值
       LinkedList.prototype.getPosition = function(position) {
            //1.越界判断
            if(position < 0 || position >= this.length) return null;
            //2.获得元素
            // 指针
            var current = this.head;
            var index = 0;
            while(index < position) {
                current = current.next;
                index++;
            }
            return current.data;
        }
5.修改指定位置(position)数据
       LinkedList.prototype.update = function(position, newData) {
            //1.越界判断
            if(position < 0 || position >= this.length) return null;
            //2.获得元素
            var current = this.head;
            var index = 0;
            while(index < position) {
                current = current.next;
                index++;
            }
            current.data = newData;
            return true;
        }
6.查找某个值的索引位置
      LinkedList.prototype.indexOf = function(data) {
            //1.定义变量
            var current = this.head;
            var index = 0;
            //2.开始查找
            while(current) {
            	// 找到节点,返回索引
                if(current.data == data) {
                    return index;
                }
                // 下一个节点
                current = current.next;
                index++;
            }
            //3.在链表中没有找到该元素,返回-1
            return -1;
        } 
7.删除指定位置数据(position),返回数据
      LinkedList.prototype.removeAt = function(position) {
            //1.越界判断
            if(position < 0 || position >= this.length) return null;
            //2.判断是否删除第一个节点
            var current = this.head;
            if(position == 0) {
                this.head = this.head.next;
            } else {
                var index = 0;
                var previous = null;
                while (index++ < position) {
                    previous = current;
                    current = current.next;
                }
                //前一个节点的next指向current的next即可
                previous.next = current.next;
            }
            // 3.长度减一
            this.length -= 1;
            return current.data;
        }
8.删除某个值对应的节点
       LinkedList.prototype.remove = function(data) {
            //1.找到data在链表中的位置
            var position = this.indexOf(data);
            //2.根据位置信息,删除节点
            return this.removeAt(position);
        }
9.判断链表是否为空
        LinkedList.prototype.isEmpty = function() {
            return this.length == 0;
        }
10.返回链表长度
        LinkedList.prototype.size = function() {
            return this.length;
        }

js中单链表与数组对比

(1)查找对应数据value

乱序数组遍历找到对应数据,复杂度O(n)
排序数组折半查找找到对应数据,复杂度O(log2n)
链表遍历查找对应数据,复杂度O(n)

(2)按索引查找

数组复杂度O(1),链表O(n)

(3)插入、删除数据

尾部插入、删除:数组复杂度O(1),链表O(n)
任意位置插入、删除:数组需要平均移动半个表长的数据,链表只需要修改前后指针即可

(4)灵活性

链表在需要时可以申请新空间,操作灵活、高效

这是在b站上看coderwhy老师的课程整理的笔记,老师的官方博客:数据结构(五)之链表结构

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值