1-单项链表

    function LinkedList() {
let Node = function(element) { // 辅助类,表示要添加到链表中的项
this.element = element;
this.next = null; //next属性是只想链表的下一个节点的指针
}; let length = 0,
head = null; // 头指针
this.append = function(element) {}; // 向链表尾部添加一个新的项
this.insert = function(element, position) {}; // 向指定位置插入一个新的项
this.removeAt = function(position) {}; // 移除链表中的指定项
this.remove = function(element) {}; // 移除值为element的项
this.indexOf = function(element) {}; // 返回元素在链表中的索引,如果没有则返回-1
this.isEmpty = function() {}; // 判断链表中是否为空
this.size = function() {}; // 链表的长度
this.clear = function() {}; // 清空链表
this.print = function() {}; //输出链表的值
}

append实现:向链表尾部添加一个新的项

        this.append = function(element) { //向链表尾部添加一个新的项
let node = new Node(element),
current;
if (head === null) { // 链表中的第一个节点
head = node;
} else {
current = head;
while (current.next) { // 循环链表,直到找到最后一项
current = current.next;
}
current.next = node; // 找到最后一项,将next赋值为node,建立连接
}
length += 1; //更新链表长度
};

print实现:输出链表的值

    this.print = function() {
let current = head;
for (let i = 0; i < length; i++) {
console.log(`第${i+1}个值:${current.element}`);
current = current.next;
}
};

insert实现:向指定位置插入一个新的项

向指定位置插入一个新的项,步骤如下:

  • 先进行position的越界判断!!
  • case1: 当position=0的时候,那就是直接将当前head指向的节点变成新建node的next指向,head指向新建的node上
  • case2: 除case1外的情况,先遍历到如下图所示的情况,我们设置两个指针,每次遍历都是current将值赋给previous,然后current向后推进,直到current指向position的位置,previous指向position的前一个

  • 然后将新建的node,插入其中,然后改变其中的指针指向,具体看代码
  • 最后将length加一
    this.insert = function(element, position) { // 向指定位置插入一个新的项
if (position >= 0 && position <= length) { // 检查越界值
let node = new Node(element),
current = head, // 设置两指针
previous;
if (position === 0) { // 在第一个位置添加
node.next = head;
head = node;
}else {
for (let i = 0; i < position; i++) {
// 使得current定在要插入的位置,previous定在要插入位置的前一个位置
previous = current;
current = current.next;
}
// 将新项node插入进去
node.next = current;
previous.next = node;
}
}else {
return 0;
}
length += 1;
};
对于函数参数含有position这类的位置参数,一定要注意越界判断

removeAt实现:移除链表中的指定位置项

removeAt的思想和前面的insert方法很相似,唯一的不同就是移除指定项时,改变指针指向的代码不同previous.next = current.next;

  • 具体思想如图:将current指向的项(其实也就是position指向的项)移除,那就将图中红色叉的指针指向取消,然后用新的代替
  • 然后将lenght减一

  • 只有previous.next = current.next;和insert方法不同,其他思想和做法都一样
            this.removeaAt = function(position) { // 移除链表中的指定项
if (position >= 0 && position <= length) {
let current = head,
previous;
if (position === 0) {
head = head.next;
}else {
for (let i = 0; i < position; i++) { //此处循环到current指向要移除的位置,同insert方法
previous = current;
current = current.next;
}
// 通过将previous的next变化到current.next,将指定项移除
previous.next = current.next;
}
}else {
return 0;
}
length -= 1;
};

indexOf实现:返回元素在链表中的索引,如果没有则返回-1

        this.indexOf = function(element) { // 返回元素在链表中的索引,如果没有则返回-1
let current = head; //
for (let i = 0; i < length; i++) {
if (current.element === element) {
return i;
}
current = current.next;
}
return -1;
};

remove实现:移除值为element的项

this.remove = function(element) { // 移除值为element的项
// remove方法可以直接通过复用 this.indexOf(element) 和 this.removeAt(position) 方法实现
let index = this.indexOf(element);
return this.removeaAt(index);
};

isEmpty、size、clear实现

this.isEmpty = function() { // 判断链表中是否为空
return length === 0;
}; this.size = function() { // 链表的长度
return length;
}; this.clear = function() { // 清空链表
let current = head;
for (let i = 0; i < length; i++) {
this.removeAt(i);
}
length = 0;
head = null;
};

测试函数

    (function LinkedListTest() {
let linked = new LinkedList();
linked.append(2);
linked.append(3);
linked.append(4);
linked.print(); // 第1个值:2 第2个值:3 第3个值:4 linked.insert(5, 1); // 位置从0开始
linked.print(); // 第1个值:2 第2个值:5 第3个值:3 第4个值:4
linked.removeAt(1); // 相当于将上面插入的5再删除
linked.print(); // 第1个值:2 第2个值:3 第3个值:4 console.log(linked.indexOf(3)); // 1
console.log(linked.indexOf(10)); // -1
console.log(linked.size()); // 3
console.log(linked.isEmpty()); // false
linked.clear();
console.log(linked.isEmpty()); // true
})();

JavaScript的数据结构快速学-链表的实现的更多相关文章

  1. JavaScript 版数据结构与算法(三)链表

    今天,我们要讲的是数据结构与算法中的链表. 链表简介 链表是什么?链表是一种动态的数据结构,这意味着我们可以任意增删元素,它会按需扩容.为何要使用链表?下面列举一些链表的用途: 因为数组的存储有缺陷: ...

  2. JavaScript数据结构与算法-链表练习

    链表的实现 一. 单向链表 // Node类 function Node (element) { this.element = element; this.next = null; } // Link ...

  3. javascript数据结构之单链表

    下面是用javascript实现的单链表,但是在输出的时候insert方法中存在问题,chrome的console报错说不能读取空的属性,调试了很久都没有通过,先在这里存着,以后再来修改一下. //数 ...

  4. 第一章:javascript: 数据结构与算法

    在前端工程师中,常常有一种声音,我们为什么要学数据结构与算法,没有数据结构与算法,我们一样很好的完成工作.实际上,算法是一个宽泛的概念,我们写的任何程序都可以称为算法,甚至往冰箱里放大象,也要通过开门 ...

  5. javascript实现数据结构与算法系列:栈 -- 顺序存储表示和链式表示及示例

    栈(Stack)是限定仅在表尾进行插入或删除操作的线性表.表尾为栈顶(top),表头为栈底(bottom),不含元素的空表为空栈. 栈又称为后进先出(last in first out)的线性表. 堆 ...

  6. Javascript模仿C语言的链表实现(增删改查),并且使用控制台输入输出

    Js新手最近在研究Js数据结构,刚好看到链表实现这一块儿,觉得有些资料和自己理解的有冲突,于是借着自己以前一点点C语言的基础,用Javascript模仿了C的链表实现,并且用了process.stdi ...

  7. javascript实现数据结构:广义表

    原文:javascript实现数据结构:广义表  广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an ...

  8. JavaScript 版数据结构与算法(二)队列

    今天,我们要讲的是数据结构与算法中的队列. 队列简介 队列是什么?队列是一种先进先出(FIFO)的数据结构.队列有什么用呢?队列通常用来描述算法或生活中的一些先进先出的场景,比如: 在图的广度优先遍历 ...

  9. 2018年如何快速学Java

    前言 只有光头才能变强 提前预警:本文适合Java新手阅读(老手可在评论区给下建议),希望大家看完能有所收获. 一.为什么我要写下这篇文章 1.1直接缘由: 在今天(2018年11月4日)有个同学给我 ...

随机推荐

  1. shell 中小括号,中括号,大括号的区别

    一.小括号,圆括号() 1.单小括号 () ①命令组.括号中的命令将会新开一个子shell顺序执行,所以括号中的变量不能够被脚本余下的部分使用.括号中多个命令之间用分号隔开,最后一个命令可以没有分号, ...

  2. BugKu之备份是个好习惯

    题目:备份是个好习惯 思路分析 打开题目,看到一个字符串. 联系到题目,就猜到肯定是源代码泄露,用工具扫一下,发现了index.php.bak,验证了我的猜想,下载下来看看. <?php /** ...

  3. PHP怎样写延时队列(定时器)

    背景 PHP没有定时器,依托的都是crontab这样的系统工具,也没有go中defer这样的延时方法,本文介绍几种PHP写延时队列的几种姿势. 延时队列的定义 普通的队列是先进先出,但是延时队列并不是 ...

  4. GoLang设计模式13 - 观察者模式

    观察者模式是一种行为型设计模式.这种模式允许一个实例(可以称为目标对象)发布各种事件(event)给其他实例(观察者).这些观察者会对目标对象进行订阅,这样每当目标对象发生变化时,观察者就会收到事件( ...

  5. Django开发 X-Frame-Options to deny 报错处理

    本博客已停更,请转自新博客查看 https://www.whbwiki.com/318.html 错误提示 Refused to display 'http://127.0.0.1:8000/inde ...

  6. JavaScript 对象:String & Array 及其常见应用

    String对象 split 功能:把字符串分割为字符串数组.官方文档已经描述的够清楚,不多赘述.主要说一下需要注意的情况以及应用 1.省略分割参数 var str="How are you ...

  7. K8S 部署 SpringBoot 项目(一篇够用)

    现在比较多的互联网公司都在尝试将微服务迁到云上,这样的能够通过一些成熟的云容器管理平台更为方便地管理微服务集群,从而提高微服务的稳定性,同时也能较好地提升团队开发效率. 但是迁云存在一定的技术难点,今 ...

  8. 2020 天翼杯 部分wp

    天翼杯 呜呜呜呜 是我太菜了 Web APItest 源码 const express = require("express"); const cors = require(&qu ...

  9. Effective C++ 总结笔记(三)

    三.资源管理 13.以对象管理资源 1.为了防止资源泄漏,请使用RAII对象,在构造函数里面获得资源,并在析构函数里面释放资源. 2. 引用计数型智慧指针(RCSP):持续追踪多少个指针指向该资源,无 ...

  10. Typora常用命令

    目录 Typora编辑器所用语法--Markdown 简介 1.Markdown --标题 2. Markdown --列表(子标题) 3. Markdown --列表嵌套 4. Markdown - ...