2023-08-13
数据结构与算法
00
请注意,本文编写于 854 天前,最后修改于 664 天前,其中某些信息可能已经过时。

场景如下:在开发中实现一个动态表单,能方便对表单项进行增删改操作,为了操作方便,给每一个节点增加pre和next属性用来指向前一个节点和后一个节点。于是想到用链表的数据结构来实现改功能(不用链表结构也能实现,只需要给每一个Node节点对象增加两个属性pre和next,在增删操作额外去维护这两个指针就行)

FormLinked.ts

ts
class FormItemNode<T extends {filed:string}> { public data: T public prev: FormItemNode<T> | null public next: FormItemNode<T> | null constructor(_data: T) { this.data = _data } } // T extends {filed:string} 需要根据filed属性判断 相等的依据 class FormLinked<T extends {filed:string}>{ /** 链表头节点 */ private head: FormItemNode<T> | null /** 链表尾节点 */ private tail: FormItemNode<T> | null /** 链表长度 */ private length = 0 get(position:number){ // 越界判断 if (position < 0 || position >= this.length) return null if (position <= this.length / 2) { // 获取对应的data let current = this.head // 定义当前值为头节点 let index = 0 // 定义索引值为0 while (index++ < position) { // 循环找到需要的 position 对应位置的值 current = current.next } return current.data } else { let current = this.tail let index = this.length - 1 while (index-- > position) { current = current.prev } return current.data } } indexOf(data:T | string){ // 定义变量 let current = this.head let index = 0 // 查找current的data与传入值的data是否相等 while (current) { if(typeof data === "string" && current.data.filed === data){ return index }else if(typeof data !== "string" && current.data.filed === data.filed){ return index } index += 1 current = current.next } return -1 } /** * 链表尾部追加 * @param data */ append(data: T) { // 1、根据data创建节点 let newNode = new FormItemNode(data) // 2、判断添加的是否是第一个节点 if (this.length == 0) { this.head = newNode this.tail = newNode } else { newNode.prev = this.tail this.tail.next = newNode this.tail = newNode } // 3、length + 1 this.length += 1 } /** * 插入到指定位置 * @param position 位置索引 * @param data * @returns */ insert(position: number, data: T) { // 越界判断 if (position < 0 || position > this.length) return false // 根据 data 创建新的节点 let newNode = new FormItemNode(data) // 判断原来的列表是否为空 if (this.length == 0) { this.head = newNode this.tail = newNode } else { if (position == 0) { // 插入到开头 this.head.prev = newNode newNode.next = this.head this.head = newNode } else if (position == this.length) { // 插入到结尾 newNode.prev = this.tail this.tail.next = newNode this.tail = newNode } else { // 插入到中间 let current = this.head let index = 0 //找到插入位置 while (index++ < position) { current = current.next } // 修改指针 newNode.next = current newNode.prev = current.prev current.prev.next = newNode current.prev = newNode } } // length + 1 this.length += 1 return true } /** * 更新指定位置的数据 * @param position * @param newData * @returns */ update(position: number, newData: T) { // 越界判断 if (position < 0 || position > this.length) return false if (position <= this.length / 2) { // 定义变量 let current = this.head let index = 0 while (index++ < position) { current = current.next } current.data = newData return true } else { // 定义变量 let current = this.tail let index = this.length - 1 while (index-- > position) { current = current.prev } current.data = newData return true } } /** * 删除指定数据的节点 * @param position * @returns */ removeAt(position: number) { // 越界判断 if (position < 0 || position > this.length) return null var current = this.head // 判断是否只有一个节点 if (this.length == 1) { this.head = null this.tail = null } else { if (position == 0) { // 判断删除的是否是第一个节点 this.head.next.prev = null this.head = this.head.next } else if (position == this.length - 1) { // 判断删除的是否是最后一个节点 current = this.tail this.tail.prev.next = null this.tail = this.tail.prev } else { // 删除的是其他的节点 let index = 0 while (index++ < position) { current = current.next } current.prev.next = current.next current.next.prev = current.prev } } // 长度减一 this.length -= 1 return current.data } /** * 删除数据 * @param data * @returns */ remove(data:T){ // 1、根据data获取下标值 let index = this.indexOf(data) // 2、根据index删除对应位置的节点 return this.removeAt(index) } isEmpty(){ return this.length === 0 } size(){ return this.length } getHead(){ return this.head } getTail(){ return this.tail } // 转换成数组 toArray(){ // 定义变量 let current = this.head let index = 0 let arr:T[] = [] while (current) { arr.push(current.data) index += 1 current = current.next } return arr } } export {FormItemNode,FormLinked}
如果对你有用的话,可以打赏哦
打赏
ali pay
wechat pay

本文作者:千寻

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!