| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262 |
- import ArrayList from './ArrayList'
- import SortedMap from './SortedMap'
- import HashSet from './HashSet'
- const BLACK = 0
- const RED = 1
- function colorOf(p) {
- return (p == null ? BLACK : p.color)
- }
- function parentOf(p) {
- return (p == null ? null : p.parent)
- }
- function setColor(p, c) {
- if (p !== null) p.color = c
- }
- function leftOf(p) {
- return (p == null ? null : p.left)
- }
- function rightOf(p) {
- return (p == null ? null : p.right)
- }
- /**
- * @see http://download.oracle.com/javase/6/docs/api/java/util/TreeMap.html
- */
- export default class TreeMap extends SortedMap {
- constructor() {
- super()
- this.root_ = null
- this.size_ = 0
- }
- get(key) {
- let p = this.root_
- while (p !== null) {
- const cmp = key.compareTo(p.key)
- if (cmp < 0)
- p = p.left
- else if (cmp > 0)
- p = p.right
- else return p.value
- }
- return null
- }
- put(key, value) {
- if (this.root_ === null) {
- this.root_ = {
- key: key,
- value: value,
- left: null,
- right: null,
- parent: null,
- color: BLACK,
- getValue() {
- return this.value
- },
- getKey() {
- return this.key
- }
- }
- this.size_ = 1
- return null
- }
- let t = this.root_; let parent; let cmp
- do {
- parent = t
- cmp = key.compareTo(t.key)
- if (cmp < 0) {
- t = t.left
- } else if (cmp > 0) {
- t = t.right
- } else {
- const oldValue = t.value
- t.value = value
- return oldValue
- }
- } while (t !== null)
- const e = {
- key: key,
- left: null,
- right: null,
- value: value,
- parent: parent,
- color: BLACK,
- getValue() {
- return this.value
- },
- getKey() {
- return this.key
- }
- }
- if (cmp < 0)
- parent.left = e
- else parent.right = e
- this.fixAfterInsertion(e)
- this.size_++
- return null
- }
- /**
- * @param {Object} x
- */
- fixAfterInsertion(x) {
- let y
- x.color = RED
- while (x != null && x !== this.root_ && x.parent.color === RED)
- if (parentOf(x) === leftOf(parentOf(parentOf(x)))) {
- y = rightOf(parentOf(parentOf(x)))
- if (colorOf(y) === RED) {
- setColor(parentOf(x), BLACK)
- setColor(y, BLACK)
- setColor(parentOf(parentOf(x)), RED)
- x = parentOf(parentOf(x))
- } else {
- if (x === rightOf(parentOf(x))) {
- x = parentOf(x)
- this.rotateLeft(x)
- }
- setColor(parentOf(x), BLACK)
- setColor(parentOf(parentOf(x)), RED)
- this.rotateRight(parentOf(parentOf(x)))
- }
- } else {
- y = leftOf(parentOf(parentOf(x)))
- if (colorOf(y) === RED) {
- setColor(parentOf(x), BLACK)
- setColor(y, BLACK)
- setColor(parentOf(parentOf(x)), RED)
- x = parentOf(parentOf(x))
- } else {
- if (x === leftOf(parentOf(x))) {
- x = parentOf(x)
- this.rotateRight(x)
- }
- setColor(parentOf(x), BLACK)
- setColor(parentOf(parentOf(x)), RED)
- this.rotateLeft(parentOf(parentOf(x)))
- }
- }
- this.root_.color = BLACK
- }
- values() {
- const arrayList = new ArrayList()
- let p = this.getFirstEntry()
- if (p !== null) {
- arrayList.add(p.value)
- while ((p = TreeMap.successor(p)) !== null)
- arrayList.add(p.value)
- }
- return arrayList
- }
- entrySet() {
- const hashSet = new HashSet()
- let p = this.getFirstEntry()
- if (p !== null) {
- hashSet.add(p)
- while ((p = TreeMap.successor(p)) !== null)
- hashSet.add(p)
- }
- return hashSet
- }
- /**
- * @param {Object} p
- */
- rotateLeft(p) {
- if (p != null) {
- const r = p.right
- p.right = r.left
- if (r.left != null)
- r.left.parent = p
- r.parent = p.parent
- if (p.parent == null)
- this.root_ = r
- else if (p.parent.left === p)
- p.parent.left = r
- else
- p.parent.right = r
- r.left = p
- p.parent = r
- }
- }
- /**
- * @param {Object} p
- */
- rotateRight(p) {
- if (p != null) {
- const l = p.left
- p.left = l.right
- if (l.right != null)
- l.right.parent = p
- l.parent = p.parent
- if (p.parent == null)
- this.root_ = l
- else if (p.parent.right === p)
- p.parent.right = l
- else
- p.parent.left = l
- l.right = p
- p.parent = l
- }
- }
- /**
- * @return {Object}
- */
- getFirstEntry() {
- let p = this.root_
- if (p != null)
- while (p.left != null) p = p.left
- return p
- }
- /**
- * @param {Object} t
- * @return {Object}
- * @private
- */
- static successor(t) {
- let p
- if (t === null) {
- return null
- } else if (t.right !== null) {
- p = t.right
- while (p.left !== null)
- p = p.left
- return p
- } else {
- p = t.parent
- let ch = t
- while (p !== null && ch === p.right) {
- ch = p
- p = p.parent
- }
- return p
- }
- }
- size() {
- return this.size_
- }
- containsKey(key) {
- let p = this.root_
- while (p !== null) {
- const cmp = key.compareTo(p.key)
- if (cmp < 0)
- p = p.left
- else if (cmp > 0)
- p = p.right
- else return true
- }
- return false
- }
- }
|