JS链、表

2022-08-30  本文已影响0人  大大大大大西瓜G

一、链表数据结构

要存储多个元素,数组(或列表)可能是最常用的数据结构。然而这种数据结构有一个缺点,数字的大小是固定的,从数组的起点或中间插入或移除项的成本很高,因为需要移动元素。
链表存储有序的元素集合,但不用于数组,链表中的元素在内存中并不是连续放置的。每个元素由一个存储元素本身的节点和一个指向下一个元素的饮用(也称指针或链接)组成。下图展示了一个链表的结构


image.png

相对于传统的数组,链表的一个好处在于,添加或移动元素的时候不需要移动其他元素。然而,链表需要使用指针,因此实现链表时需要额外注意。数组的一个细节是可以直接访问任何位置的元素,而想要访问链表中间的一个元素,需要从起点(表头)开始迭代列表直到找到所需的元素。
举几个形象的例子来形容:

特点

二、创建链表

下面我们实现一个链表类,并给他加点方法

class Node {  //节点类
    //构造函数
    constructor(item) { 
        this.item = item;
        this.next = null;
    }
}
class LinkedList {  // 链表类
    //构造函数
    constructor() { 
        this.head = null;
        this.length = 0;
    }
    //新增节点
    append(item) { 
        let node = new Node(item);
        let current; //暂存当前位置
        if(this.head === null) { // 如果头结点为空,当前节点作为头结点
            this.head = node;
        } else { 
            current = this.head;
            while(current.next) {     //遍历找到链表尾部
                current = current.next;
            }
            current.next = node;    //在链表尾部加入新节点
        }
        this.length++; //更新链表长度
    }
    //删除节点,并获得删除节点的值
    remove(index) { 
        if(index > -1 && index < this.length) { //预防下标越界
            var current = this.head;//暂存当前位置
            var previous; //暂存当前位置的前一个
            var position = 0;
            if(index === 0) {  //要删除的是第一个位置,就得改变头指针指向
                this.head = current.next;
            } else { 
                while(position++ < index) { //遍历直到current处于index位置
                    previous = current;
                    current = current.next;  //此时current处于index处,previous在index-1处
                }
                previous.next = current.next; //改变链表结构,跳过index处
            }
            this.length--; //更新链表长度
            return current.[图片上传中...(image.png-aecada-1661950439992-0)]
; //返回index处的值
        } else { 
            return null;    //下标越界返回空
        }
    }
    //插入节点
    insert(index, item) {
        if(index > -1 && index <= this.length) { 
            let node = new Node(item);
            let current = this.head;
            let previous;
            let position = 0;
            if(index === 0) { 
                node.next = current;
                this.head = node;
            } else { 
                while(position++ < index) { 
                    previous = current;
                    current = current.next;
                }
                node.next = current;
                previous.next = node;
            }
            length++;
            return true; //插入成功
        } else { 
            return false; //插入失败
        }
    }
    //获取索引
    indexOf(item) { 
        let current = this.head;
        let position = 0;
        while(current) { 
            if(current.item === item) { 
                return position;
            }
            position++;
            current = current.next;
        }
        return -1; //未找到索引
    }
    //将链表转换成字符串
    toString() { 
        let current = this.head;
        let string = '';
        while(current) { 
            string += current.item + ((current.next ? ',': ''));
            current = current.next;
        }
        return string;
    }
    //链表长度
    size() { 
        return this.length;
    }
    //判断链表是否为空
    isEmpty() { 
        return this.length === 0;
    }
}

这样我们就实现了一个链表类,我们也为其添加了很多自定义方法

未完待续......

上一篇下一篇

猜你喜欢

热点阅读