数据结构篇(2) ts实现单循环链表
JS的class可以通过extends关键字实现类似其他语言的继承效果,比起使用一个extends关键字,在es5中实现继承要复杂一些,可以通过修改原型链的方法实现继承,让一个原型对象等于另一个类型的实例等等,虽然也能够实现,但是不够直观。
constructor()方法中的super()表示调用父类的构造函数,在这里就是调用SIngleList类里面的构造函数。
接下来就可以使用SingleList类中已经实现的函数了,但是由于单向循环链表的某些操作还是不同于单链表的,所以对SingleList类中的一些方法,需要在CirSingleList类中重写。
//继承单链表的属性和方法,有一些方法需要重写
class CirListNode extends ListNode {
constructor() {
super()
}
// 在单循环链表中寻找最后一个节点
/** 使用count进行计数,如果与当前链表的长度相同就返回子节点,这样就可以避免陷入无限循环*/
findLast(): NodeItem {
let count = 0;
let currNode = this.head;
while (currNode.next) {
currNode = currNode.next;
count++;
if (count === this.size) {
return currNode;
}
}
return this.head;
}
// 在单循环链表中寻找数据
/** 如果对应元素不存在会导致无限循环,
所以需要重写搜索函数,如果当前节点等于最后一个子节点就结束循环返回null*/
find(item: any): NodeItem {
let lastNode = this.findLast();
let currNode = this.head;
while (currNode.data != item) {
if (currNode == lastNode) {
currNode = null;
break;
}
currNode = currNode.next;
}
return currNode;
}
// 在数据为item的节点后面插入数据为element元素的节点
/**
* 1. 插入的是头节点位置,如果当前链表为空,则将新节点插入到head节点后面,并指向自己,形成循环
* 2,插入的是头节点位置,当前链表不为空,则将新节点指向头节点的下一个节点,然后再将头节点指向新节点,再将尾节点指向新节点,形成一个新的循环
* 3, 插入的是中间位置,就正常插入即可
*/
insert(item: any, element: any): void {
let newNode = new NodeItem(element);
let itemNode = this.find(item);
let lastNode = this.findLast();
// 插入的位置处于头结点之后,第一个节点之前
if (item === 'head') {
if (this.size === 0) {
this.head.next = newNode;
newNode.next = newNode;
} else {
newNode.next = this.head.next;
this.head.next = newNode;
lastNode.next = newNode;
}
this.size++;
return;
}
// 处于链表中后位置时
newNode.next = itemNode.next;
itemNode.next = newNode;
this.size++;
}
/**
* 1. 当前删除的节点是第一个节点时,如果此时单向循环链表只有一个节点,直接将此单向链表置空即可
* 2. 当前删除的节点是第一个节点时, 且此时单向循环链表不仅只有一个节点时,此时将头节点的next指针指向要删除节点的下一个节点,并将最后一个节点指向要删除节点的下一个节点
* 3. 除了前面的两种情况之外,只要将删除节点的前一个节点next指针指向要删除节点的后一个系欸但即可
*/
remove(item: any): void {
let lastNode = this.findLast();
let itemNode = this.find(item);
let preCurNode = this.head;
while (preCurNode.next !== itemNode) {
preCurNode = preCurNode.next;
}
if (itemNode === this.head.next) {
if (this.size === 1) {
this.head.next = null;
} else {
this.head.next = itemNode.next;
lastNode.next = itemNode.next;
}
} else {
preCurNode.next = itemNode.next;
}
this.size--;
}
/**
* 根据count计数来输出链表内容,防止陷入无限循环
*/
display(): void {
let count = 0;
let currNode = this.head;
let str = '';
while (count !== this.size) {
currNode = currNode.next;
str += currNode.data + '=>';
count++;
}
console.log(str)
}
/**
* 在尾部插入数据
* 用写好的findLast()方法,找到最后一个节点,然后将最后一个节点next指针指向新的节点,再将新的节点指向此链表的第一个节点即可。
*/
append(element: any): void {
let lastNode = this.findLast();
let newNode = new NodeItem(element);
lastNode.next = newNode;
newNode.next = this.head.next;
this.size++;
}
}
// n个人围成一圈,杀死第m个人,直到剩下s个人为止
// 输出存活的人的序号
let myList = new CirListNode();
function killPerson(n: any, m: any, s: any) {
for (let i = 1; i <= n; i++) {
myList.append(i);
}
let currNode = undefined;
let toKill = null;
while(myList.size>s) {
toKill = myList.advance(m, currNode); // 从currNode开始,前进m个节点
currNode = toKill; // 保存要删除的节点作为下一次循环的参数
myList.remove(toKill.data); // 删除第m个节点
}
myList.display();
}
killPerson(41, 3, 2); // head->16->31
// killPerson(5, 4, 1); // head->1
数据结构篇(2) ts实现单循环链表的更多相关文章
- 数据结构篇(2) ts实现单链表
interface NodeItem { prev: NodeItem | null next: NodeItem | null data: any } class NodeItem { prev: ...
- 新秀nginx源代码分析数据结构篇(两) 双链表ngx_queue_t
nginx源代码分析数据结构篇(两) 双链表ngx_queue_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csdn. ...
- 菜鸟nginx源代码剖析数据结构篇(八) 缓冲区链表ngx_chain_t
菜鸟nginx源代码剖析数据结构篇(八) 缓冲区链表 ngx_chain_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog. ...
- 菜鸟nginx源码剖析数据结构篇(八) 缓冲区链表ngx_chain_t[转]
菜鸟nginx源码剖析数据结构篇(八) 缓冲区链表 ngx_chain_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.c ...
- 菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t[转]
菜鸟nginx源码剖析数据结构篇(三) 单向链表 ngx_list_t Author:Echo Chen(陈斌) Email:chenb19870707@gmail.com Blog:Blog.csd ...
- 数据结构篇(3)ts 实现双向链表
如今终于到了双向链表了,此前在Node结构中的prev指针终于派上了用场.由于双向链表多了一个前向指针,所以有些操作和单向链表比较起来反而更加的简单. class DbList extends Cir ...
- 数据结构篇(1) ts实现栈的基本操作和解决相关问题
interface Stack { _items: any push(element: any): void pop(): any top(): any size(): any isEmpty(): ...
- 图解Redis之数据结构篇——链表
前言 Redis链表为双向无环链表! 图解Redis之数据结构篇--简单动态字符串SDS提到Redis使用了简单动态字符串,链表,字典(散列表),跳跃表,整数集合,压缩列表这些数据结构 ...
- 图解Redis之数据结构篇——简单动态字符串SDS
图解Redis之数据结构篇--简单动态字符串SDS 前言 相信用过Redis的人都知道,Redis提供了一个逻辑上的对象系统构建了一个键值对数据库以供客户端用户使用.这个对象系统包括字符串对象 ...
随机推荐
- 【Python 第0课】Why Python?
为什么用Python作为编程入门语言? 原因很简单. 嗯...原因就是,很简单... 每种语言都会有它的支持者和反对者.去Google一下"why python"(程序员准则:要G ...
- switch 是否能作用在byte 上,是否能作用在long 上,是否能作用在String上?
答:在Java 5以前,switch(expr)中,expr只能是byte.short.char.int.从Java 5开始,Java中引入了枚举类型,expr也可以是enum类型,从Java 7开始 ...
- 要多简单就有多简单的H5拍照加水印
来一个简单粗暴的gif演示图 先来html 内容 <video id="video" width="320" height="240" ...
- 微信小程序黑客马拉松即将开始,来做最酷的 Mini Program Creators!
微信小程序黑客马拉松正式启动 近日,小程序斩获一项世界级殊荣--作为一项全新的技术和应用创新,小程序首次获选世界互联网领先科技成果.目前小程序应用数量已超过 100 万,覆盖了 200 多个细分行业, ...
- 小程序web开发框架-weweb介绍
weweb是一个兼容小程序语法的前端框架,你可以用小程序的写法,来写web单面应用.如果你已经有小程序了,通过它你可以将你的小程序运行在浏览器中.在小程序大行其道的今天,它可以让你的小程序代码得到最大 ...
- vue和mint-ui loadMore 实现上拉加载和下拉刷新
首先安装mint-ui组件库 npm install mint-ui 在main.js中引入mint-ui和样式 import 'mint-ui/lib/style.css' import MintU ...
- python爬取梦幻西游召唤兽资质信息(不包含变异)
一.分析 1.爬取网站:https://xyq.163.com/chongwu/ 2.获取网页源码: request.get("https://xyq.163.com/chongwu/&qu ...
- 利用window对象自带atob和btoa方法进行base64的编码和解码
项目中一般需要将表单中的数据进行编码之后再进行传输到服务器,这个时候就需要base64编码 现在可以使用window自带的方法window.atob() 和 window.btoa() 方法进行 ...
- C语言,最大公约数---更相减损术
// 最大公约数 更相减损法 int commonDivisor() { int i,k,n=0; printf("请输入两个不同的正整数,用,隔开\n"); scanf(&quo ...
- caioj 1000到1030都是[水题]
caioj 1000到1030都是[水题],特此声明一下,可以不做就不要浪费时间做了