JS中的链表结构

1 相对于数组的优缺点

链表的优点:

  • 内存空间不必连续,可以充分利用计算机的内存,实现灵活的内存动态管理
  • 链表不必在创建时就确定其大小,并且大小可以无限的延伸下去
  • 链表在插入和删除数据时,时间复杂度可以达到O(1),相对数组效率高很多

链表的缺点:

  • 链表访问任何一个位置的元素时,都需要从头开始访问。(无法跳过第一个元素访问任何一个元素)
  • 无法通过下标直接访问元素,需要从头一个个访问,直到找到对应的元素
    在这里插入图片描述

2 链表的常见操作

  • append(element):向列表尾部添加一个新的项
  • insert(position, element):向列表的特定位置插入一个新的项。
  • remove(element):从列表中移除一项。
  • indexOf(element):返回元素在列表中的索引。如果列表中没有该元素则返回-1。
  • removeAt(position):从列表的特定位置移除一项。
  • isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0则返回false。
  • size():返回链表包含的元素个数。与数组的length属性类似。
  • toString():由于列表项使用了Node类,就需要重写继承自JavaScript对象默认的toString方法,让其只输出元素的值。

3 链表结构的封装

//封装链表类
        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.判断是否添加的是第一个节点
                if(this.length === 0){   //2.1 是第一个节点
                    this.head = newNode
                }else{                    //2.1 不是第一个节点
                    var current = this.head;
                    // 找到最后一个节点
                    while(current.next){
                        current = current.next;
                    }
                    //最后一个节点的next指向新的节点
                    current.next = newNode;
                }
                //3 链表长度加1
                this.length++;
            }

            //2、toString方法
            LinkedList.prototype.toString = function() {
                //1.定义变量
                var current = this.head;
                var listString = "";

                //2.循环一个个节点
                while(current){
                    listString += current.data + " ";
                    current = current.next;
                }
                return listString;
            }

            //3、insert方法:把数据插入当前链表的某个位置
            LinkedList.prototype.insert = function(position,data) {
                //1.对position进行越界判断
                if(position<0||position>this.length){
                    return null;
                }

                //2.根据data创建newNode
                var newNode = new Node(data);

                //3 插入节点
                //情况1:插入position=0的值
                if(position === 0){
                    newNode.next = this.head.next;
                    this.head = newNode;
                }else{
                    //情况2: 插入position>0的值
                    var index = 0;
                    var current = this.head;
                    while(index < position-1){ 
                        current = current.next;
                        index++;
                    }
                    newNode.next = current.next;
                    current.next = newNode;
                }
                //4、length+1
                this.length++;
                return true;
            }
            //4、get方法:获取某个位置的元素
            LinkedList.prototype.get = function (position){
                //1.越界判断
                if(position<0||position>=this.length){
                    return null;
                }else{
                    //2.获取对应的data
                    var current = this.head;
                    var index = 0;
                    while(index < position){
                        current = current.next;
                        index++;
                    }
                    return current.data;
                }
            }
            //5、indexOf方法:返回某个元素在链表中的位置
            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;

            }
            //6、update方法:修改某个位置的元素
            LinkedList.prototype.update = function(position,newData){
                //1.越界判断
                if(position < 0 || position >= this.length){
                    return false
                }else{
                    //2.查找正确的节点
                    var current = this.head;
                    var index = 0;
                    while(index < position){
                        current = current.next;
                        index++;
                    }
                    //3.将position位置的node的data修改成newData
                    current.data = newData;
                    return true;
                }
            }
            //7、removeAt方法:移除某个位置的元素
            LinkedList.prototype.removeAt = function(position){
                //1.越界判断
                if(position < 0 || position >= this.length){
                    return false;
                }else{
                    if(position === 0){ //2.如果position = 0
                        this.head = this.head.next;
                    }else{              //3.如果position != 0
                        var index = 0;
                        var current = this.head;
                        while(index < position-1){
                            current = current.next;
                            index++;
                        }
                        current.next = current.next.next;
                    }
                    this.length--;
                }
            }
            //8、remove方法:移除数据为data的元素
            LinkedList.prototype.remove = function(data){
                //1.获取data在列表中的位置
                var position = this.indexOf(data);
                return this.removeAt(position);
                this.length--;
            }
            //9、isEmpty方法,判断链表是否为空
            LinkedList.prototype.isEmpty = function(){
                return this.length === 0;
            }
            //10、size方法,返回链表包含的元素个数
            LinkedList.prototype.size = function(){
                return this.length;
            }
        }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值