Skip to content

Instantly share code, notes, and snippets.

@liuqinh2s
Last active October 27, 2022 05:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liuqinh2s/2a419b21947b55a1f77f88c8082f9cf6 to your computer and use it in GitHub Desktop.
Save liuqinh2s/2a419b21947b55a1f77f88c8082f9cf6 to your computer and use it in GitHub Desktop.
Typescript写的双链表数据结构,可以拿来刷leetcode,用来弥补js没有自带双链表的不足
class LinkedListNode<T>{
value: T;
next: LinkedListNode<T>;
prev: LinkedListNode<T>;
constructor(value?:T, next?: LinkedListNode<T>, prev?: LinkedListNode<T>){
this.value = value;
this.next = next;
this.prev = prev;
}
}
class LinkedList<T> {
private head = new LinkedListNode<T>();
private tail = new LinkedListNode<T>();
private _length = 0;
get length():number{
return this._length;
}
private set length(value: number){
this._length = value;
}
constructor(){
this.head.next = this.tail;
this.tail.prev = this.head;
}
first():T{
return this.action(this.head.next, 'get');
}
last():T{
return this.action(this.tail.prev, 'get');
}
push(value:T){
this.action(this.tail.prev, 'add', value);
}
pop():T{
const last = this.last();
this.action(this.tail.prev, 'delete');
return last;
}
shift():T{
const first = this.first();
this.action(this.head.next, 'delete');
return first;
}
unshift(value:T){
this.action(this.head.next, 'add', value);
}
get(index: LinkedListNode<T> | number): T{
return this.action(this.search(index), 'get');
}
set(index: LinkedListNode<T> | number, value: T){
this.action(this.search(index), 'set', value);
}
add(index: LinkedListNode<T> | number, value: T){
this.action(this.search(index), 'add', value);
}
delete(index: LinkedListNode<T> | number){
this.action(this.search(index), 'delete');
}
action(p: LinkedListNode<T>, actionType: 'get'|'set'|'add'|'delete', value?:T): T{
if(!p || ((p === this.head || p === this.tail) && actionType !== 'add')){
return;
}
switch(actionType){
case 'get':{
return p.value;
}
case 'set':{
p.value = value;
break;
}
case 'add':{
const node = new LinkedListNode(value, p.next, p);
p.next.prev = node;
p.next = node;
this.length++;
break;
}
case 'delete':{
p.next.prev = p.prev;
p.prev.next = p.next;
this.length--;
break;
}
}
}
search(index: number | LinkedListNode<T>, direction: 'forward'|'backward' = 'forward'): LinkedListNode<T>{
let p;
if(index instanceof LinkedListNode){
if(direction==='backward'){
p = this.head;
while(p && p!==index){
p = p.next;
}
}else{
p = this.tail;
while(p && p!==index){
p = p.prev;
}
}
return p;
} else if(typeof index === 'number') {
const i = Math.abs(index);
if(index<0){
p = this.tail;
for(let j=0;j<i && p;j++){
p = p.prev;
}
}else{
p = this.head;
for(let j=-1;j<i && p;j++){
p = p.next;
}
}
}
return p;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment