js链表的实现

js链表的实现

linkedList.js

class Node {
    constructor(data) {
        this.data = data;
        this.next = null;
    }
}

class LinkedList {
    constructor() {
        this.head = null;
        this.tail = this.head;
        this.length = 0;
    }

    /**
     * 遍历链表
     * @param callback
     */
    iterator(callback) {
        let current = this.head;
        let prevNode = null;
        let nextNode = current.next;
        while (current) {
            callback(prevNode,current,nextNode);
            prevNode = current;
            current = current.next || null;
            nextNode = current?.next || null;
        }
    }

    /**
     * 获取指定元素的索引
     * @param {*} node
     * @param {*} keyField
     * @returns
     */
    indexOf(node,keyField) {
        let current = this.head;
        let index = 1; // 记录元素的位置
        while (current) {
            // 循环遍历链表
            if(keyField) {
                if(current.data[keyField] === node.data[keyField]) {
                    // 如果当前节点的值等于元素的值
                    return index; // 返回位置
                } else {
                    // 如果不等于,继续循环
                    current = current.next;
                    index++;
                }
            } else {
                if(current.data === node.data) {
                    // 如果当前节点的值等于元素的值
                    return index; // 返回位置
                } else {
                    // 如果不等于,继续循环
                    current = current.next;
                    index++;
                }
            }
        }
        return -1; // 循环结束了,说明没找到
    }

    /**
     * 修改节点数据
     * @param {*} data
     */
    set(index,data) {
        const { currNode } = this.getContext(index);
        currNode.data = data;
    }

    /**
     * 顺序添加节点
     * @param {*} data
     */
    append(data) {
        const newNode = new Node(data);
        if(!this.head) {
            this.head = newNode;
            this.tail = newNode;
        } else {
            this.tail.next = newNode;
            this.tail = newNode;
        }
        this.length++;
        return newNode;
    }

    /**
     * 将值添加到链表的开头
     * @param {*} data
     */
    prepend(data) {
        const newNode = new Node(data);

        newNode.next = this.head;
        this.head = newNode;
        this.length++;
    }

    /**
     * 获取当前索引节点的上下文
     * @param {*} index
     * @returns
     */
    getContext(index) {
        let count = 1;
        let prevNode = null;
        let currNode = this.head;
        let nextNode = currNode ? currNode.next : null;

        while (count < index) {
            prevNode = currNode;
            currNode = currNode ? currNode.next : null;
            nextNode = nextNode ? nextNode.next : null;
            count++;
        }

        return {
            prevNode,
            currNode,
            nextNode,
        };
    }

    /**
     * 在特定索引之后添加值
     * @param {*} data
     * @param {*} index
     */
    insert(data,index) {
        if(index < 1 || index > this.length) {
            console.error("插入失败,索引超出");
            return;
        }

        const newNode = new Node(data);

        const { currNode,nextNode } = this.getContext(index);
        currNode.next = newNode;
        newNode.next = nextNode;

        this.length++;
    }

    /**
     * 删除特定索引处的元素
     * @param {*} index
     */
    remove(index) {
        if(index < 1 || index > this.length) {
            console.error("删除失败,索引超出");
            return;
        }
        const { prevNode,currNode } = this.getContext(index);

        if(prevNode) {
            prevNode.next = currNode.next;
        } else {
            this.head = currNode.next;
        }
        this.length--;
    }

    /**
     * 调换元素位置
     */
    swapNodes(node1,node2,keyField) {
        const index1 = this.indexOf(node1,keyField);
        const index2 = this.indexOf(node2,keyField);

        const { prevNode: prevNode1,nextNode: nextNode1 } = this.getContext(index1);
        const { prevNode: prevNode2,nextNode: nextNode2 } = this.getContext(index2);

        prevNode1.next = node2;
        node2.next = nextNode1;

        prevNode2.next = node1;
        node1.next = nextNode2;
    }

    /**
     * 翻转链表
     */
    reverse() {
        let previousNode = null;
        let currentNode = this.head;

        while (currentNode !== null) {
            let nextNode = currentNode.next;
            currentNode.next = previousNode;
            previousNode = currentNode;
            currentNode = nextNode;
        }

        this.head = previousNode;
    }
}

export { LinkedList };
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值