js 实现链表的常规操作

简介: js 实现链表的常规操作
// 创建一个链表
/**
 * 创建一个链表的节点,每一个链表都是跟节点
 * @param value
 * @constructor
 */
function Node(value) {
    this.value = value;
    this.next = null;
}
let a = new Node('a');
let b = new Node('b');
let c = new Node('c');
let d = new Node('d');
let w = new Node('w');
a.next = b;
b.next = c;
c.next = d;
/**
 * 获取链表的长度,原型方法
 * @returns {number}
 */
Node.prototype.length = function () {
    let temp = this, index = 0;
    while (temp) {
        index++;
        temp = temp.next;
    }
    return index;
}
/**
 * 获取链表的长度,直接方法
 * @param root
 * @returns {number|*}
 */
function length(root) {
    if (!root) return 0;
    return 1 + getLength(root.next);
}
/**
 * 变量链表原型方法
 */
Node.prototype.print = function () {
    function _print(root) {
        if (!root) return;
        console.log(root.value);
        _print(root.next);
    }
    _print(this);
}
/**
 * 打印链表的方法
 * @param root
 * @returns {null}
 */
function print(root) {
    if (!root) return null;
    let temp = root;
    while (temp) {
        console.log(temp.value);
        temp = temp.next;
    }
}
/**
 * 通过下标获取链表的值, 原型方法
 * @param i
 * @returns {null}
 */
Node.prototype.getValue = function (i) {
    if (!this || i < 0 || i >= this.length()) return null;
    function _getValue(root, index) {
        if (!root) return null;
        else if (index === i) return root.value;
        else return _getValue(root.next, index + 1);
    }
    return _getValue(this, 0);
}
/**
 * 通过下标给链表设置值
 * @param i
 * @param val
 */
Node.prototype.setValue = function (i, val) {
    if (!this || i < 0 || i > this.length()) return;
    function _setValue(root, index) {
        if (!root) return
        else if (index === i) root.value = val;
        else _setValue(root.next, index + 1);
    }
    _setValue(this, 0)
}
/**
 * 判断链表是否存在某个节点
 * @param node {Node} 节点
 * @returns {boolean}
 */
Node.prototype.has = function (node) {
    if (!this) return false;
    let temp = this;
    while (temp) {
        if (node instanceof Node && node.value === temp.value) return true;
        else temp = temp.next;
    }
    return false
}
/**
 * 判断节点是否存在链表中
 * @param root{Node}
 * @param node{Node}
 * @returns {boolean}
 */
function has(root, node) {
    if (!root) return false;
    if (node instanceof Node && node.value === root.value) return true;
    else return has(root.next, node);
}
/**
 * 在一个节点之后加入一个新的节点
 * @param node {Node}
 * @param val {String | Number}
 * @returns {boolean}
 */
Node.prototype.insertAfterNode = function (node, val) {
    if (!this || !this.has(node)) return;
    let temp = this;
    while (temp) {
        if (node instanceof Node && temp === node) {
            let newNode = new Node(val);
            newNode.next = temp.next;
            temp.next = newNode;
            return true;
        }
        temp = temp.next;
    }
}
/**
 * 在链表的任意一个节点后面插入一个新的节点
 * @param root {Node} 链表
 * @param node {Node} 节点
 * @param val {String | Number}
 */
function insertAfterNode(root, node, val) {
    if (!root || !has(root, node)) return;
    if (node instanceof Node && root === node) {
        let newNode = new Node(val);
        newNode.next = root.next;
        root.next = newNode;
    } else {
        insertAfterNode(root.next, node, val);
    }
}
/**
 * 链表最后加入一个新的节点
 * @param val {Number | String}
 * @returns {boolean|void}
 */
Node.prototype.push = function (val) {
    if (!this) return false;
    let temp = this;
    while (temp) {
        if (!temp.next) {
            temp.next = new Node(val);
            return this.print();
        }
        temp = temp.next;
    }
}
/**
 * 在链表的最后加入新的节点
 * @param root {Node}
 * @param val {String | Number}
 * @returns {boolean}
 */
function push(root, val) {
    if (!root) return false;
    if (!root.next) {
        root.next = new Node(val);
    } else push(root.next, val);
}
/**
 * 通过节点删除一个节点
 * @param node {Node}
 * @returns {boolean|void}
 */
Node.prototype.del = function (node) {
    if (!this || !this.has(node) || node === this) return false;
    let temp = this;
    while (temp) {
        if (temp.next === node && node instanceof Node) {
            let nextNode = temp.next;
            temp.next = temp.next.next;
            nextNode.next = null;
            return this.print();
        } else temp = temp.next;
    }
}
/**
 * 删除一个节点
 * @param root {Node}
 * @param node {Node}
 * @returns {boolean}
 */
function del(root, node) {
    if (!root || !has(root, node) || (root === node && node instanceof Node)) return false;
    else if (root.next === node) {
        let rootNextNode = root.next;
        root.next = root.next.next;
        rootNextNode.next = null;
    } else del(root.next, node);
}
/**
 * 字符串的逆置
 */
Node.prototype.reverse = function () {
    if (!this) return;
    function _reverse(root) {
        if (!root) return;
        if (!root.next.next) {
            let node = root.next;
            root.next.next = root;
            root.next = null;
            return node;
        } else {
            let res = _reverse(root.next);
            root.next.next = root;
            root.next = null;
            return res;
        }
    }
    return _reverse(this).print();
}
相关文章
|
6月前
|
前端开发 JavaScript 数据处理
在JavaScript中,异步函数是指那些不会立即执行完毕,而是会在未来的某个时间点(比如某个操作完成后,或者某个事件触发后)才完成其执行的函数
【6月更文挑战第15天】JavaScript中的异步函数用于处理非同步任务,如网络请求或定时操作。它们使用回调、Promise或async/await。
54 7
|
6月前
|
JSON 前端开发 JavaScript
在JavaScript中,异步编程是一种处理非阻塞操作(如网络请求、文件读写等)的重要技术
【6月更文挑战第12天】JavaScript中的异步编程通过Promise和async/await处理非阻塞操作。Promise管理异步操作的三种状态,防止回调地狱,支持链式调用和并行处理。async/await是ES8引入的语法糖,使异步代码更像同步代码,提高可读性。两者结合使用能更高效地处理复杂异步场景。
40 3
|
4月前
|
存储 JavaScript 前端开发
JavaScript实现单向链表
JavaScript实现单向链表
25 0
|
6月前
|
JavaScript 前端开发 UED
JavaScript基础-DOM操作:查找、创建、修改
【6月更文挑战第12天】本文介绍了DOM基础,包括查找元素(getElementById、getElementsByClassName等)、创建新节点(createElement、createTextNode)和修改节点(innerText、innerHTML、setAttribute等)。强调了易错点,如ID唯一性、性能考量和安全问题,并提供了代码示例。熟练掌握DOM操作对前端开发至关重要,但应注意性能优化,适时使用框架或库。
69 2
JavaScript基础-DOM操作:查找、创建、修改
|
5月前
|
JavaScript 前端开发 索引
JavaScript编码之路 【JavaScript之操作数组、字符串方法汇总】(三)
JavaScript编码之路 【JavaScript之操作数组、字符串方法汇总】(三)
47 1
|
5月前
|
存储 JavaScript 前端开发
js/javascript 操作字符串【全】(含常用的操作字符串的lodash)
js/javascript 操作字符串【全】(含常用的操作字符串的lodash)
46 1
|
6月前
|
JavaScript vr&ar 数据库
技术笔记:Js获取当前日期时间及其它操作
技术笔记:Js获取当前日期时间及其它操作
142 1
|
6月前
|
存储 前端开发 JavaScript
回调函数是JavaScript中处理异步编程的常见模式,常用于事件驱动和I/O操作。
【6月更文挑战第27天】回调函数是JavaScript中处理异步编程的常见模式,常用于事件驱动和I/O操作。它作为参数传递给其他函数,在特定条件满足或任务完成后被调用。例如,`asyncOperation`函数接受回调函数`handleResult`,模拟异步操作后,调用`handleResult`传递结果。这样,当异步任务完成时,`handleResult`负责处理结果。
40 1
|
6月前
|
JavaScript 前端开发 安全
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
安全开发-JS应用&原生开发&JQuery库&Ajax技术&加密编码库&断点调试&逆向分析&元素属性操作
|
6月前
|
存储 JavaScript 前端开发
JavaScript中的数组是核心数据结构,用于存储和操作序列数据
【6月更文挑战第22天】JavaScript中的数组是核心数据结构,用于存储和操作序列数据。创建数组可以使用字面量`[]`或`new Array()`。访问元素通过索引,如`myArray[0]`,修改同样如此。常见方法包括:`push()`添加元素至末尾,`pop()`移除末尾元素,`shift()`移除首元素,`unshift()`添加到开头,`join()`连接为字符串,`slice()`提取子数组,`splice()`进行删除、替换,`indexOf()`查找元素位置,`sort()`排序数组。还有其他如`reverse()`、`concat()`等方法。
133 2