add ts supported

This commit is contained in:
許 志偉 2019-05-16 11:03:06 +09:00
parent c96dd3d565
commit b8098c4677
4 changed files with 378 additions and 0 deletions

View File

@ -0,0 +1,106 @@
/**
* Map和双向链表实现的LRU算法
* 使
*/
class LRUCache<K, V> {
private cacheMap: Map<K, LinkedListNode<K, V>>
private readonly limit: number
private head: LinkedListNode<K, V> | null = null
private end: LinkedListNode<K, V> | null = null
constructor(limit: number) {
if (limit <= 0) throw new Error('limit of cache must > 0')
this.cacheMap = new Map()
this.limit = limit
}
public get(key: K): V | null {
const node = this.cacheMap.get(key)
if (!node) return null
this.refreshNode(node)
return node.value
}
public put(key: K, value: V) {
const node = this.cacheMap.get(key)
// 原缓存不存在则加入到队尾
if (!node) {
// 大于规定的size则删除最不常用的
if (this.cacheMap.size >= this.limit) {
const oldKey = this.removeNode(this.head!)
this.cacheMap.delete(oldKey)
}
// 在队尾添加
const newNode = new LinkedListNode(key, value)
this.addNode(newNode)
this.cacheMap.set(key, newNode)
} else {
node.value = value
this.refreshNode(node)
}
}
private refreshNode(node: LinkedListNode<K, V>) {
if (node === this.end) return
this.removeNode(node)
this.addNode(node)
}
private removeNode(node: LinkedListNode<K, V>): K {
if (node === this.end) {
this.end = this.end.prev
} else if (node === this.head) {
this.head = this.head.next
} else {
// 这个由于排除了首尾节点
node.prev!.next = node.next
node.next!.prev = node.prev
}
return node.key
}
/**
*
* @param node
*/
private addNode(node: LinkedListNode<K, V>) {
if (this.end) {
this.end.next = node
node.prev = this.end
}
this.end = node
if (this.head === null) {
this.head = node
}
// 消除之前的节点的下一个引用对象,防止无限循环
node.next = null
}
}
class LinkedListNode<K, V> {
key: K
value: V
next: LinkedListNode<K, V> | null
prev: LinkedListNode<K, V> | null
constructor(
key: K,
value: V,
next: LinkedListNode<K, V> | null = null,
prev: LinkedListNode<K, V> | null = null
) {
this.key = key
this.value = value
this.next = next
this.prev = prev
}
}
const cache = new LRUCache<string,string>(3)
cache.put('lv','xzw')
cache.put('lv2','xzw2')
cache.put('lv3','xzw3')
cache.put('lv4','xzw4')
cache.put('lv5','xzw5')
console.log(cache)

View File

@ -0,0 +1,132 @@
/**
*
*
*/
import List from './List'
class LinkedList<T> implements List<T> {
size: number = 0
private head: LinkedListNode<T> | null = null
private last: LinkedListNode<T> | null = null
findByIndex(index: number): LinkedListNode<T> | null {
let p = this.head
let pos = 0
while (p && pos !== index) {
p = p.next
pos++
}
return p
}
findByValue(value: T): LinkedListNode<T> | null {
let p = this.head
while (p && p.item !== value) {
p = p.next
}
return p
}
insertToHead(value: T): void {
let p = this.head
const newNode = new LinkedListNode(value)
// 没有元素的时候需要初始化头节点和尾节点
if (!p) {
this.last = this.head = newNode
} else {
p.prev = newNode
newNode.next = p
this.head = newNode
}
this.size++
}
/**
* index后面插入节点
* @param value
* @param index
*/
insertToIndex(value: T, index: number): void {
let p = this.head
let pos = 0
const newNode = new LinkedListNode(value)
while (p !== null && pos !== index) {
p = p.next
pos++
}
if (p === null) return
newNode.next = p.next
p.next = newNode
newNode.prev = p
this.size++
}
insertToTail(value: T): void {
let p = this.last
const newNode = new LinkedListNode(value)
if (p === null) {
this.head = this.last = newNode
} else {
p.next = newNode
newNode.prev = p
this.last = newNode
}
this.size++
}
remove(value: T): boolean {
let p = this.head
while (p && p.item !== value) {
p = p.next
}
if (!p) return false
if (p.prev) {
p.prev.next = p.next
} else {
this.head = p.next
}
if (p.next) {
p.next.prev = p.prev
} else {
this.last = p.prev
}
this.size--
return true
}
toString(): string {
let ret: string = ''
let p = this.head
while (p) {
ret = `${ret} ${p.item} `
p = p.next
}
return ret
}
}
class LinkedListNode<T> {
item: T
next: LinkedListNode<T> | null
prev: LinkedListNode<T> | null
constructor(
item: T,
next: LinkedListNode<T> | null = null,
prev: LinkedListNode<T> | null = null
) {
this.item = item
this.next = next
this.prev = prev
}
}
const linkedList = new LinkedList()
linkedList.insertToHead('12')
linkedList.insertToHead('haha')
linkedList.insertToHead('www')
linkedList.insertToTail('zxc')
linkedList.insertToIndex('12ooo', 0)
linkedList.remove('12oooo')
console.log(linkedList.toString())

View File

@ -0,0 +1,19 @@
interface List<T> {
insertToHead(value: T): void
findByValue(value: T): any
findByIndex(index: number): any
insertToIndex(value: T, index: number): void
remove(value: T): boolean
insertToHead(value: T): void
insertToTail(value: T): void
toString(): string
}
export default List

View File

@ -0,0 +1,121 @@
/**
* 1)
* 2)
*/
import List from './List'
class SingleLinkedList<T> implements List<T> {
// 哨兵头节点
private readonly head: SingleNode<T>
constructor() {
this.head = new SingleNode<any>(null)
}
public findByValue(value: T): SingleNode<T> | null {
let p = this.head
while (p.next != null) {
if (p.next.value === value) return p.next
p = p.next
}
return p.next
}
public findByIndex(index: number): SingleNode<T> | null {
let p = this.head
let pos = 0
while (p.next != null && pos !== index) {
p = p.next
pos++
}
return p.next
}
/**
*
* @param value
* @param index
*/
public insertToIndex(value: T, index: number): void {
const newNode = new SingleNode(value)
let p = this.head
let pos = 0
while (p.next != null && pos !== index) {
p = p.next
pos++
}
if (p.next == null) return
newNode.next = p.next.next
p.next.next = newNode
}
/**
*
* @param value 1 0
*/
public remove(value: T): boolean {
let p = this.head
while (p.next != null) {
if (p.next.value === value) break
p = p.next
}
if (p.next === null) return false
p.next = p.next.next
return true
}
public insertToHead(value: T): void {
const newNode = new SingleNode(value, null)
this.insertNodeToHead(newNode)
}
public insertToTail(value: T): void {
const newNode = new SingleNode(value, null)
this.insertNodeToTail(newNode)
}
private insertNodeToHead(node: SingleNode<T>): void {
node.next = this.head.next
this.head.next = node
}
public toString(): string {
let ret: string = ''
let p = this.head
while (p.next != null) {
ret = `${ret} ${p.next.value} `
p = p.next
}
return ret
}
/**
*
* @param newNode
*/
private insertNodeToTail(newNode: SingleNode<T>): void {
let p = this.head
while (p.next != null) {
p = p.next
}
p.next = newNode
}
}
class SingleNode<T> {
value: T
next: SingleNode<T> | null
constructor(value: T, next: SingleNode<T> | null = null) {
this.value = value
this.next = next
}
}
const singleLinkedList = new SingleLinkedList<string>()
singleLinkedList.insertToTail('god')
singleLinkedList.insertToTail('my')
// console.log(singleLinkedList.printLinkedList())
singleLinkedList.insertToIndex('haha', 1)
singleLinkedList.remove('ha1')
singleLinkedList.toString()