js数据结构与算法 第二天(链表,双向链表)

本文深入解析链表数据结构,涵盖单向链表和双向链表的实现与操作,包括追加、插入、删除等方法,以及如何遍历链表。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链表(线性结构)

链表中的元素在内存中不必是连续的空间,实现灵活的内存动态管理;不必在创建的时候确定大小,大小可以无限延申;链表在插入和删除数据时,时间复杂度可以达到O(1),非常高效;但是链表访问任何一个位置的元素时,都需要从头开始访问
在这里插入图片描述
单向链表的封装
里面封装了多种方法,都添加了注释

function linkedList() {
    //内部的类 这里可以在参数里面传next也可以不传
    function Node(data) {
        this.data = data;
        this.next = null;
    }
    this.head = null;
    this.length = 0;

    //1.追加方法
    linkedList.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;
        }
        //有些语言不支持++,所以写成+=1
        this.length += 1;
    }

    //2.toString()方法
    linkedList.prototype.toString = function() {
        var current = this.head;
        var listString = '';
        while (current) {
            listString += current.data + ' ';
            current = current.next;
        }
        return listString;
    }

    //3.insert()方法
    linkedList.prototype.insert = function(position, data) {
        //对position进行越界判断
        //对链表的长度进行判断
        //注意这里是大于length 可以等于length
        if (position < 0 || position > this.length) {
            return false;
        } else {
            var newNode = new Node(data);
            if (position == 0) {
                newNode.next = this.head;
                this.head = newNode;
            } else {
                var index = 0;
                var previous = null;
                var current = this.head;
                while (index++ < position) {
                    previous = current;
                    current = current.next;
                }
                newNode.next = current;
                previous.next = newNode;
            }
            this.length += 1;
            return newNode.data;
        }
    }

    //4.get方法
    linkedList.prototype.get = function(position) {
        //越界判断
        if (position < 0 || position >= this.length) {
            return null;
        }
        //获取数据
        else {
            var current = this.head;
            var index = 0;
            while (index++ < position) {
                current = current.next;
            }
            return current.data;
        }
    }

    //5.indexOf()方法
    linkedList.prototype.indexOf = function(data) {
        var current = this.head;
        var index = 0;
        while (current) {
            if (current.data == data) {
                return index;
            }
            current = current.next;
            index += 1;
        }
        return -1;
    }

    //6.update()方法
    linkedList.prototype.update = function(position, newdata) {
        //越界判断
        if (position < 0 || position >= this.length) {
            return null;
        }
        //修改数据
        else {
            var current = this.head;
            var index = 0;
            while (index++ < position) {
                current = current.next;
            }
            current.data = newdata;
        }
    }

    //7.removeAt()方法
    linkedList.prototype.removeAt = function(position) {
        var current = this.head;
        //越界判断
        if (position < 0 || position >= this.length) {
            return null;
        } else {
            if (position == 0) {
                this.head = this.head.next;
            } else {
                var index = 0;
                var previous = null;
                while (index++ < position) {
                    previous = current;
                    current = current.next;
                }
                previous.next = current.next;
            }
            this.length -= 1;
            return current.data;
        }

    }

    //8.remove()方法
    linkedList.prototype.remove = function(data) {
        var position = this.indexOf(data);
        return this.removeAt(position);
    }

    //9.isEmpty()方法
    linkedList.prototype.isEmpty = function() {
        return this.length == 0;
    }

    //10.size()方法
    linkedList.prototype.size = function() {
        return this.length;
    }

}

双向链表

在这里插入图片描述

双向链表的封装

function DoublyLinkedList() {
    this.head = null;
    this.tail = null;
    this.length = 0;

    function Node(data) {
        this.data = data;
        this.prev = null;
        this.next = null;
    }

    //1.append()方法
    DoublyLinkedList.prototype.append = function(data) {
        //创建新节点
        var newNode = new Node(data);
        //判断添加的是否是第一个节点
        if (this.length == 0) {
            this.head = newNode;
            this.tail = newNode;
        }
        //不是第一个节点
        else {
            newNode.prev = this.tail;
            this.tail.next = newNode;
            this.tail = newNode;
        }
        //有些语言不支持++,所以写成+=1
        this.length += 1;
    }

    //2.toString()方法
    DoublyLinkedList.prototype.toString = function() {
        return this.backwardString();
    }

    //3.forwardString() 向前遍历方法
    DoublyLinkedList.prototype.forwardString = function() {
        var current = this.tail;
        var listString = '';
        while (current) {
            listString += current.data + ' ';
            current = current.prev;
        }
        return listString;
    }

    //4.backwardString() 向后遍历方法
    DoublyLinkedList.prototype.backwardString = function() {
        var current = this.head;
        var listString = '';
        while (current) {
            listString += current.data + ' ';
            current = current.next;
        }
        return listString;
    }

    //5.insert()方法
    DoublyLinkedList.prototype.insert = function(position, data) {
        //越界判断
        if (position < 0 || position > this.length) {
            return false;
        } else {
            //创建新的节点
            var newnode = new Node(data)
            //判断原来的链表是否为空
            if (this.length == 0) {
                this.head = newnode;
                this.tail = newnode;
            } else {
                if (position == 0) {
                    this.head.prev = newnode;
                    newnode.next = this.head;
                    this.head = newnode;
                } else if (position == this.length) {
                    newnode.prev = this.tail;
                    this.tail.next = newnode;
                    this.tail = newnode;
                } else {
                    var current = this.head;
                    var index = 0;
                    //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;
    }

    //6.get()方法
    DoublyLinkedList.prototype.get = function(position) {
        //越界判断
        if (position < 0 || position >= this.length) {
            return null;
        } else {
            if (position < this.length / 2) {
                var current = this.head;
                var index = 0;
                while (index++ < position) {
                    current = current.next;
                }
                return current.data;
            } else {
                var current = this.tail;
                var index = this.length - 1;
                while (index-- > position) {
                    current = current.prev;
                }
                return current.data;
            }
        }
    }

    //7.indexOf()方法
    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 += 1;
            }
        }
        return -1;
    }

    //8.update()方法
    DoublyLinkedList.prototype.update = function(position, newdata) {
        //越界判断
        if (position < 0 || position >= this.length) {
            return flase;
        } else {
            var current = this.head;
            var index = 0;
            while (index++ < position) {
                current = current.next;
            }
            current.data = newdata;
            return true;
        }
    }

    //9.removeAt()方法
    DoublyLinkedList.prototype.removeAt = function(position) {
        var current = this.head;
        //越界判断
        if (position < 0 || position >= this.length) {
            return null;
        } else {
            if (this.length == 1) {
                this.head = null;
                this.tail = null;
            } else {
                if (position == 0) {
                    this.head.next.prev = null;
                    this.head = current.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;
    }

    //10.remove()方法
    DoublyLinkedList.prototype.remove = function(element) {
        var index = this.indexOf(element);
        return this.removeAt(index);
    }

    //11.isEmpty()方法
    DoublyLinkedList.prototype.isEmpty = function() {
        return this.length == 0;
    }

    //12.size()方法
    DoublyLinkedList.prototype.size = function() {
        return this.length;
    }

    //13.获取链表的第一个元素
    DoublyLinkedList.prototype.getHead = function() {
        return this.head.data;
    }

    //14.获取链表的最后一个元素
    DoublyLinkedList.prototype.getTail = function() {
        return this.tail.data;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值