Merge pull request #313 from jsrdxzw/master

add typescript supported
This commit is contained in:
wangzheng0822 2019-05-20 16:05:01 +08:00 committed by GitHub
commit 4d1ff58273
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 512 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> {
public value: T
public 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()

View File

@ -0,0 +1,134 @@
/**
*
*
*
*
* n个节点
*
*/
class LinkedListAlog {
/**
* ,
* @param list
*/
public static reverse<T>(list: SingleNode<T>): SingleNode<T> | null {
let currentNode: SingleNode<T> | null = list
let prevNode = null
while (currentNode) {
const nextNode: SingleNode<T> | null = currentNode.next
currentNode.next = prevNode
prevNode = currentNode
currentNode = nextNode
}
return prevNode
}
/**
*
* @param list
*/
public static checkCircle<T>(list: SingleNode<T>): boolean {
if (!list) return false
let fast: SingleNode<T> | null = list.next
let slow: SingleNode<T> | null = list
while (fast && fast.next) {
fast = fast.next.next
slow = slow!!.next
if (fast === slow) return true
}
return false
}
/**
*
* @param list
* @param index
*/
public static removeFromEnd<T>(list: SingleNode<T>, index: number): SingleNode<T> | null {
// 如果是个环,就没必要找了
if (this.checkCircle(list)) return list
let newNode = this.reverse(list)
let preNode = null
let pos = 0
while (newNode && pos !== index) {
newNode = newNode.next
pos++
preNode = newNode
}
if (!newNode) return null
if (preNode) {
preNode.next = newNode.next
}
return this.reverse(newNode)
}
public static findMidNode<T>(list: SingleNode<T>): SingleNode<T> | null {
if (!list) return null
let fast = list.next
let slow = list
while (fast && fast.next) {
fast = fast.next.next
slow = slow.next!!
}
return slow
}
/**
*
* @param a
* @param b
*/
public static mergeSortedLists<T>(a: SingleNode<T>, b: SingleNode<T>): SingleNode<T> | null {
if (!a || !b) return a ? a : b
let p: SingleNode<T> | null = a
let q: SingleNode<T> | null = b
// 新链表的头部指针
let newList: SingleNode<T> | null = null
if (p.value < q.value) {
newList = p
p = p.next
} else {
newList = q
q = q.next
}
let currNode = newList
while (p && q) {
if (p.value < q.value) {
currNode.next = p
p = p.next
} else {
currNode.next = q
q = q.next
}
currNode = currNode.next
}
if (p) {
currNode.next = p
} else {
currNode.next = q
}
return newList
}
}
class SingleNode<T> {
public value: T
public next: SingleNode<T> | null
constructor(value: T, next: SingleNode<T> | null = null) {
this.value = value
this.next = next
}
}
const node1 = new SingleNode(1)
node1.next = new SingleNode(3)
node1.next.next = new SingleNode(5)
const node2 = new SingleNode(2)
node2.next = new SingleNode(7)
node2.next.next = new SingleNode(8)
node2.next.next.next = new SingleNode(10)
console.log(LinkedListAlog.findMidNode(node1))