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 ...
随机推荐
- celery+django+mq 异步任务与定时任务
参考 celerypip install celery==4.1.1https://www.cnblogs.com/wdliu/p/9530219.htmlhttps://www.jianshu.co ...
- HTML5——2 HTML5视频
在以往我们还是使用flash来进行播放视频,但是它有先天的缺陷,比如,很多的浏览器并不会直接去支持flash插件,需要你自己去安装,而且版本也很难去统一,也有浏览器先天集成了这个插件,比如Chrome ...
- Java入门第二季——Java中的this关键字
如果想访问一个private属性,通常会使用setter和getter方法来操作属性,属性名经常会与参数名相同,我们为了区分属性和参数的概念,我们会在属性前面加上this关键字,此时代表我将一个参数的 ...
- Permission denied (publickey,gssapi-keyex,gssapi-with-mic)
当出现警告的时候,恭喜你,你已经离成功很近了. 远程主机这里设为slave2,用户为Hadoop. 本地主机设为slave1 以下都是在远程主机slave2上的配置,使得slave1可以免密码连接到s ...
- 干货 | 以太坊Mist负责人教你建立无服务器应用
作者:Alex Van de Sande译者:王建/蔡佳慧译者介绍: 王建:万云平台区块链技术专家,拥有多年应用系统架构经验,目前在区块链落地方面进行积极探索 蔡佳慧:万云平台实习生,区块链技术爱好者 ...
- run zabbix with docker
#!/bin/bashdocker run --name some-zabbix-server-mysql -p 10051:10051 --net=host -e DB_SERVER_HOST=&q ...
- python中else与finally的总结
1.else的用法 对try...except的补充: else子句的使用比在子句中添加其他代码更好,try因为它避免了意外捕获由try... except语句保护的代码未引发的异常. for arg ...
- ACM-ICPC 2016 沈阳赛区现场赛 I. The Elder && HDU 5956(斜率DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5956 题意:一颗树上每条边有个权值,每个节点都有新闻要送到根节点就是1节点,运送过程中如果不换青蛙就是 ...
- Clone failed: Could not read from remote repository
问题: 使用idea下载项目代码时报错,内容如下: Clone failed: Could not read from remote repository 解决方案: 把 SSH切换成 HTTP重新c ...
- 桥接模式(Bridge)---结构型
1 基础知识 定义:将抽象部分与它的具体实现部分分离,使得它们都可以独立变化.特征:通过组合的方式建立两个之间的联系而不是继承. 使用场景:抽象和具体实现之间增加更多的灵活性:一个类存在两个(多个)独 ...