es6 实现单链表
第一种
/**
* 链表节点类
*/
class Node {
constructor(ele) {
this.ele = ele;
this.next = null;
}
}
/**
* 链表类
*/
class NodeList {
constructor(ele) {
this.head = new Node(ele); //初始化链表的头节点
}
findPreNode(item) {
let currentNode = this.head;
while (currentNode && currentNode.next && currentNode.next.ele !== item) {
if (currentNode.next) {
currentNode = currentNode.next;
} else {
currentNode = null;
} }
return currentNode;
}
findNode(item) {
let currentNode = this.head; while (currentNode && currentNode.ele !== item) {
if (currentNode.next) {
currentNode = currentNode.next;
} else {
currentNode = null;
}
} return currentNode;
}
findLastNode() {
let currentNode = this.head;
while (currentNode.next) {
currentNode = currentNode.next;
}
return currentNode;
}
append(newItem, preItem) {
let newNode = new Node(newItem);
if (preItem) { // 判读是否是插入到指定节点后面,如果不是则插入到最后一个节点。
let currentNode = this.findNode(preItem);
newNode.next = currentNode.next;
currentNode.next = newNode;
} else {
let lastNode = this.findLastNode();
lastNode.next = newNode;
}
}
remove(item) {
let preNode = this.findPreNode(item); // 找到前一节点,将前一节点的next指向该节点的next
if (preNode.next != null) {
preNode.next = preNode.next.next;
}
}
toString() {
let currentNode = this.head; let strList = [];
while (currentNode.next) {
strList.push(JSON.stringify(currentNode.ele));
currentNode = currentNode.next;
}
strList.push(JSON.stringify(currentNode.ele)); return strList.join(' ==> ')
}
/* 逆置分析
单链表分为带头节点和不带头节点两种,逆置思路有两种,第一种是采用头插法重新建立新的单链表,该方法直接遍历链表,每次将当前结点添加到新链表的头部;第二种是通过该表*next指针,定义三个指针*pre, *p, *r,分别表示三个连续结点,将p->next指向pre,但 同时p的后继节点会断开,所以需要用r保存其后继节点。
*/
// 头插法
reverse () {
let p = null;
let current = this.head;
while (current !== null) {
const temp = current.next;
current.next = p;
p = current;
current = temp;
}
return p;
} // 1 -> 2 -> 3 -> 4
// r
// 修改*next指针
reverse2 () {
let pre = null;
let p = null;
let r = null;
r = this.head;
while (r !== null) {
if (p === null) {
p = r;
r = r.next;
p.next = null;
continue;
}
pre = p;
p = r;
r = r.next;
p.next = pre;
}
return p;
}
}
let A = { name: 'A', age: 10 },
B = { name: 'B', age: 20 },
C = { name: 'C', age: 30 },
D = { name: 'D', age: 40 },
E = { name: 'E', age: 50 }; let nList = new NodeList(A); nList.append(C);
nList.append(B);
nList.append(D);
nList.append(E, A);
console.log(" " + nList);
nList.remove(C);
console.log(" now " + nList)
origin: {"name":"A","age":10} ==> {"name":"E","age":50} ==> {"name":"C","age":30} ==> {"name":"B","age":20} ==> {"name":"D","age":40}
now: {"name":"A","age":10} ==> {"name":"E","age":50} ==> {"name":"B","age":20} ==> {"name":"D","age":40}
第二种
/**
* 链表节点类
*/
class Node {
constructor (ele) {
this.ele = ele;
this.next = null;
}
}
/**
* 链表类
*/
class NodeList {
constructor (ele) {
this.head = null; // 初始化链表的头节点
this.lenght = 0;
}
/**
* 尾部插入数据
* @param {*} ele
*/
append (ele) {
let newNode = new Node(ele);
let currentNode;
if (this.head === null) {
this.head = newNode;
} else {
currentNode = this.head;
while (currentNode.next) {
currentNode = currentNode.next;
}
currentNode.next = newNode;
}
this.lenght++;
}/**
* 项链表某个位置插入元素
* @param {*} position
* @param {*} ele
*/
insert (position, ele) {
if (position >= 0 && position <= this.lenght) {
let newNode = new Node(ele);
let currentNode = this.head;
let pre;
let index = 0;
if (position === 0) {
newNode.next = currentNode;
this.head = newNode;
} else {
while (index < position) {
pre = currentNode;
currentNode = currentNode.next;
index++;
}
newNode.next = currentNode;
pre.next = newNode;
}
this.lenght++;
} else {
return new Error('位置超出范围');
}
}
removeAt (position) {
if (position >= 0 && position < this.lenght) {
let currentNode = this.head;
let pre;
let index = 0;
if (position === 0) {
this.head = currentNode.next;
} else {
while (index < position) { // 1,2,3
pre = currentNode;
currentNode = currentNode.next;
index++;
}
pre.next = currentNode.next;
}
this.lenght--;
} else {
return new Error('删除位置有误');
}
}
find (ele) {
let currentNode = this.head;
let index = 0;
while (currentNode) {
if (JSON.stringify(currentNode.ele) === JSON.stringify(ele)) {
return index;
} else {
index++;
currentNode = currentNode.next;
}
}
return -1;
}
// 判断链表是否为空
isEmpty () {
return this.length === 0;
}
size () {
return this.length;
}
// 返回头
getHead () {
return this.head;
}
toString () {
let current = this.head;
let str = '';
while (current) {
str += JSON.stringify(current.ele) + ' => ';
current = current.next;
}
return str;
}
}
let A = { name: 'A', age: 10 }; let B = { name: 'B', age: 20 }; let C = { name: 'C', age: 30 }; let D = { name: 'D', age: 40 }; let E = { name: 'E', age: 50 }; let nList = new NodeList(); nList.append(A);
nList.append(C);
nList.append(B);
nList.append(D);
nList.append(E);
// console.log(JSON.stringify(nList, null, 2));
console.log(' origin: ' + nList);
nList.removeAt(2);
console.log(' now: ' + nList);
origin: {"name":"A","age":10} => {"name":"C","age":30} => {"name":"B","age":20} => {"name":"D","age":40} => {"name":"E","age":50} =>
now: {"name":"A","age":10} => {"name":"C","age":30} => {"name":"D","age":40} => {"name":"E","age":50} =>
参照:https://blog.csdn.net/qq_40941722/article/details/94381637
es6 实现单链表的更多相关文章
- 时间复杂度分别为 O(n)和 O(1)的删除单链表结点的方法
有一个单链表,提供了头指针和一个结点指针,设计一个函数,在 O(1)时间内删除该结点指针指向的结点. 众所周知,链表无法随机存储,只能从头到尾去遍历整个链表,遇到目标节点之后删除之,这是最常规的思路和 ...
- 单链表的C++实现(采用模板类)
采用模板类实现的好处是,不用拘泥于特定的数据类型.就像活字印刷术,制定好模板,就可以批量印刷,比手抄要强多少倍! 此处不具体介绍泛型编程,还是着重叙述链表的定义和相关操作. 链表结构定义 定义单链表 ...
- Java实现单链表的各种操作
Java实现单链表的各种操作 主要内容:1.单链表的基本操作 2.删除重复数据 3.找到倒数第k个元素 4.实现链表的反转 5.从尾到头输出链表 6.找到中间节点 7.检测链表是否有环 8.在 ...
- [LeetCode] Linked List Cycle II 单链表中的环之二
Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Foll ...
- c++单链表基本功能
head_LinkNode.h /*单链表类的头文件*/#include<assert.h>#include"compare.h"typedef int status; ...
- 单链表、循环链表的JS实现
数据结构系列前言: 数据结构作为程序员的基本知识,需要我们每个人牢牢掌握.近期我也展开了对数据结构的二次学习,来弥补当年挖的坑...... 当时上课的时候也就是跟着听课,没有亲自实现任何一种数据结 ...
- C代码实现非循环单链表
C代码实现非循环单链表, 直接上代码. # include <stdio.h> # include <stdlib.h> # include <malloc.h> ...
- 分离的思想结合单链表实现级联组件:CascadeView
本文介绍自己最近做省市级联的类似的级联功能的实现思路,为了尽可能地做到职责分离跟表现与行为分离,这个功能拆分成了2个组件并用到了单链表来实现关键的级联逻辑,下一段有演示效果的gif图.虽然这是个很常见 ...
- 数据结构:单链表结构字符串(python版)添加了三个新功能
#!/urs/bin/env python # -*- coding:utf-8 -*- #异常类 class stringTypeError(TypeError): pass #节点类 class ...
随机推荐
- Linux上jdk,mysql,tomcat安装
一:RPM(红帽软件包管理器):相当于windows的添加/卸载程序(控制面板),进行程序的安装.更新.卸载.查看: 本地程序安装:rpm -ivh 程序名 本地程序查看:rpm -qa 本地程序卸载 ...
- 在springmvc框架中,通过ajax请求,响应至前端的中文显示是?
今天遇到的一个问题,我通过ajax请求去访问控制器,然后通过控制器给我响应了一段json数据,但是里面的中文 在浏览上显示是??,我在web.xml 文件中是设置了编码过滤器的,但是估计这个编码过滤器 ...
- Linux--查询文件的第几行到第几行命令
cat catalina.out | tail -n +14000 | head -n 10000 | sort | uniq -c linux 如何显示一个文件的某几行(中间几行)[一]从第3000 ...
- 从Excel中读取数据并批量写入MySQL数据库(基于MySQLdb)
一.Excel内容如下,现在需要将Excel中的数据全部写入的MySQL数据库中: 二.连接MySQL的第三方库使用的是“MySQLdb”,代码如下: # -*- coding:utf-8 -*-im ...
- HTML嵌入多媒体对象
[问题描述]如何在HTML中嵌入pdf.word,音频(如mp3),视频(如mp4),flash呢? [分析] 1 嵌入pdf (1) 利用object <object classid=&quo ...
- 使用Ajax中get请求发送Token时踩的那些坑
在使用惯了各种牛X的插件以后,在使用原生组件写一些小东西的时候总是有踩不完的坑! 今天就来说一说我使用原生ajax请求时踩得坑: 下面是我的代码: var xmlhttp; if (window.XM ...
- 云主机用samba服务实现和windows共享文件
最近刚刚入坑了百度云的云主机BCC,准备在云主机上实现samba服务,映射到本机来当硬盘使用,可是一直怎么试都不成功,后来咨询客服之后才知道samba默认使用的端口445端口被运营商封禁了,只好更改端 ...
- 如何从word中直接复制图片到编辑器中
Chrome+IE默认支持粘贴剪切板中的图片,但是我要发布的文章存在word里面,图片多达数十张,我总不能一张一张复制吧?Chrome高版本提供了可以将单张图片转换在BASE64字符串的功能.但是无法 ...
- 洛谷P3935 Calculation [数论分块]
题目传送门 格式难调,题面就不放了. 分析: 实际上这个就是这道题的升级版,没什么可讲的,数论分块搞就是了. Code: //It is made by HolseLee on 18th Jul 20 ...
- Codeforces 915E. Physical Education Lessons(动态开点线段树)
E. Physical Education Lessons 题目:一段长度为n的区间初始全为1,每次成段赋值0或1,求每次操作后的区间总和.(n<=1e9,q<=3e5) 题意:用线段树做 ...