Generics with Linked List
Codealong template:
type ListNode<T> = LLNode<T> | null;
export class LLNode<T> {
constructor(
private _data: T,
public next: ListNode<T> = null) { }
get data(): T {
return this._data
}
set data(payload) {
this._data = payload
}
}
export class LinkedList<T> {
constructor(
private head: ListNode<T> = null,
private tail: ListNode<T> = null,
public length: number = 0) { }
add(data: T): void {
let node = new LLNode<T>(data)
if (this.head === null) {
this.head = node
} else {
let current = this.tail
current.next = node
}
this.tail = node
this.length++
}
insert(index: number, data: T): void {
if (index >= this.length) {
this.add(data)
} else {
let node = new LLNode<T>(data)
let current = this.head
if (index === 0) {
node.next = current
this.head = node
} else {
let currentIndex = 0;
while (currentIndex < index - 1) {
current = current.next
currentIndex++
}
node.next = current.next
current.next = node
}
this.length++
}
}
delete<T>(deleteIndex: number): T {
if (this.length > 0 && deleteIndex <= this.length - 1) {
let result
if (deleteIndex === 0) {
result = this.head.data
this.length--
if (this.head.next) {
this.head = this.head.next
return result
} else {
this.head = null
this.tail = null
return result
}
} else {
let currentIndex = 0
let current = this.head
let previous
while (currentIndex < deleteIndex) {
previous = current
current = current.next
currentIndex++
}
result = current.data
if (deleteIndex === this.length - 1) {
this.tail = previous
}
previous.next = current.next
this.length--
return result
}
} else {
return null
}
}
print(): void {
if (this.head !== null) {
let arr: any[] = []
let current = this.head
while (current.next !== null) {
arr.push(current.data)
current = current.next
}
arr.push(current.data)
console.log(arr)
} else {
console.log('empty list')
}
}
}
Stack and Queue from Linked List
export class Storable<T> {
constructor(
protected store: LinkedList<T> = new LinkedList<T>()
) { }
print(): void {
this.store.print()
}
get length(): number {
return this.store.length
}
}
export class Stack<T> extends Storable<T> {
push(data: T): void {
this.store.add(data)
}
pop(): T {
return this.store.delete(this.store.length - 1)
}
}
export class Queue<T> extends Storable<T>{
enqueue(data: T): void {
this.store.add(data)
}
dequeue(): T {
return this.store.delete(0)
}
}
Putting them to work
const s = new Stack<number>() // s, is implicitly typed as a Stack that only accepts numbers
s.push(3) // ok!
s.push(0xf00d) // weird, but ok!
s.push('Hello, world') // TSError: Argument of type '"Hello, world"' is not assignable to parameter of type 'number'.
Last updated