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. 访问所有HTTPS网站显示连接不安全 (火狐浏览器)

    当 Firefox 连接到一个安全的网站时(网址最开始为"https://"),它必须确认该网站出具的证书有效且使用足够高的加密强度.如果证书无法通过验证,或加密强度过低,Fire ...

  2. hdu 5170 GTY's math problem(水,,数学,,)

    题意: 给a,b,c,d. 比较a^b和c^d的大小 思路: 比较log(a^b)和log(c^d)的大小 代码: int a,b,c,d; int main(){ while(scanf(" ...

  3. openssh 7.4 升级 8.3

    1.删除旧版本(如果是远程连接升级,不能卸载旧版本,否则连接会断开.安装8.3完也不能卸载7.4,否则要到服务器直连重新安装8.3.) # rpm -qa |grep openssh #rpm -e ...

  4. IDM使用教程:利用IDM下载百度网盘文件

    IDM是什么 其实我使用IDM下载器只是为了方便网页版百度网盘直接下载大于40M文件而已,大家知道文件过大必须打开客户端才能下载,这点对于我的破电脑感觉很烦躁,每次要等待它慢悠悠打开,然后动用我的超级 ...

  5. PE节表详细分析

    目录 PE节表详细分析 0x00 前言 0x01 PE节表分析 节表结构 节表数量 节表名字 节表大小 节位置 节表属性 0x02 代码编写 PE节表详细分析 0x00 前言 上一篇文章我们学习了PE ...

  6. vue-router 4 你真的熟练吗?

    虽然 vue-router 4 大多数 API 保持不变,但是在 vue3 中以插件形式存在,所以在使用时有一定的变化.接下来就学习学习它是如何使用的. 一.安装并创建实例 安装最新版本的 vue-r ...

  7. docker容器命令(一)

    容器命令 创建容器:docker run 参数: -it 交互 -d 后台 –name 容器名 -p 主机端口:容器端口 (主机端口映射到docker端口) docker run --name cen ...

  8. 解决虚拟机linux系统全屏问题

    修改设置 1) 如下图右单击虚拟机名,选择[settings-],调出虚拟机设置界面. 2) 在设置界面选择[hardware]->[CD/DVD2(IDE)]->[Connection] ...

  9. nose在python2与python3中的包的自动发现用例的区别

    最近在使用python3,同样装了nose,发现自动发现用例总是有问题,如下面的代码结婚 testcase |------ __init__.py |------ test_bb.py test_bb ...

  10. dotnet templating 定制自己的项目模板

    由于工作需要,研究了一下VS 项目模板生成的相关内容,本文做一下记录借助.NET Core Template Engine创建一个加单的项目模板. 创建项目代码和配置文件 首先创建一个Minimal ...