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 设备驱动与应用程序异步通知
一.异步通知机制简介 异步通知机制的意思:一旦设备准备就绪,可以主动的通知应用程序进行相应的操作,从而使得应用程序不必去查询设备的状态. 异步通知比较准确的称谓是"信号驱动的异步IO&quo ...
- Python 实现快递查询
实现效果: 源代码: import urllib.request import json import msvcrt kd_dict = {1:'shentong',2:'youzhengguonei ...
- Gym - 101492I 区间限制费用流
https://cn.vjudge.net/problem/Gym-101492I 如果用单个点代表每个区间 利用拆点来限制区间的流量的话 点是 n^2/2+m个 边是2*n^2条 但是这样会T 解法 ...
- .configurable:可配执行 .enumerble:枚举性 .writable:可读写性 .value:数据值
configurable:控制属性能否被删除,只有当属性的configurable特性的值为true时,该属性才能够被删除. 默认值为false,即不可删除) var person = {}; Obj ...
- 字典(dict)
定义 In [4]: dt1 = {'name':'ray','age':18,'height':175} In [5]: dt1 Out[5]: {'name': 'ray', 'age': 18, ...
- 查看API工具 https://editor.swagger.io/
The base URL for the API is: https://api.cloud.nalantis.com/api/ The OpenAPI documentation is ava ...
- node中的stream(流)内置模块
stream是Node.js提供的又一个仅在服务区端可用的模块,目的是支持“流”这种数据结构. 什么是流?流是一种抽象的数据结构.想象水流,当在水管中流动时,就可以从某个地方(例如自来水厂)源源不断地 ...
- 如何优雅地防止MLE(for linux)
赛前最后一天模拟赛又有小伙伴MLE了--这里就讲一下如何较为精确地获取程序运行时间和空间. 资源统计当然是操作系统统计的最精确.所以可以这样写(noilinux实测通过,windows下应该不行): ...
- lyc——2019.10.31
10:判决素数个数 总时间限制: 1000ms 内存限制: 65536kB 描述 输入两个整数X和Y,输出两者之间的素数个数(包括X和Y). 输入 两个整数X和Y(1 <= X,Y <= ...
- CodeForces 754C Vladik and chat ——(xjbg)
虽然是xjbg的题目,但是并不很好做. 题意不难理解.读入有点麻烦.做法是先正着推每段对话的?可能是谁说的,然后反过来选择即可.正推时,其中vis数组表示谁已经被用过了,cnt表示该组当前可以选择几个 ...