Guest User

Untitled

a guest
Jan 16th, 2017
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.56 KB | None | 0 0
  1. // AVLTree ///////////////////////////////////////////////////////////////////
  2. // This file is originally from the Concentré XML project (version 0.2.1)
  3. // Licensed under GPL and LGPL
  4. //
  5. // Modified by Jeremy Stephens.
  6.  
  7. // Pass in the attribute you want to use for comparing
  8. function AVLTree(n, attr) {
  9. this.init(n, attr);
  10. }
  11.  
  12. AVLTree.prototype.init = function(n, attr) {
  13. this.attr = attr;
  14. this.left = null;
  15. this.right = null;
  16. this.node = n;
  17. this.depth = 1;
  18. this.elements = [n];
  19. };
  20.  
  21. AVLTree.prototype.balance = function() {
  22. var ldepth = this.left == null ? 0 : this.left.depth;
  23. var rdepth = this.right == null ? 0 : this.right.depth;
  24.  
  25. if (ldepth > rdepth + 1) {
  26. // LR or LL rotation
  27. var lldepth = this.left.left == null ? 0 : this.left.left.depth;
  28. var lrdepth = this.left.right == null ? 0 : this.left.right.depth;
  29.  
  30. if (lldepth < lrdepth) {
  31. // LR rotation consists of a RR rotation of the left child
  32. this.left.rotateRR();
  33. // plus a LL rotation of this node, which happens anyway
  34. }
  35. this.rotateLL();
  36. } else if (ldepth + 1 < rdepth) {
  37. // RR or RL rorarion
  38. var rrdepth = this.right.right == null ? 0 : this.right.right.depth;
  39. var rldepth = this.right.left == null ? 0 : this.right.left.depth;
  40.  
  41. if (rldepth > rrdepth) {
  42. // RR rotation consists of a LL rotation of the right child
  43. this.right.rotateLL();
  44. // plus a RR rotation of this node, which happens anyway
  45. }
  46. this.rotateRR();
  47. }
  48. };
  49.  
  50. AVLTree.prototype.rotateLL = function() {
  51. // the left side is too long => rotate from the left (_not_ leftwards)
  52. var nodeBefore = this.node;
  53. var elementsBefore = this.elements;
  54. var rightBefore = this.right;
  55. this.node = this.left.node;
  56. this.elements = this.left.elements;
  57. this.right = this.left;
  58. this.left = this.left.left;
  59. this.right.left = this.right.right;
  60. this.right.right = rightBefore;
  61. this.right.node = nodeBefore;
  62. this.right.elements = elementsBefore;
  63. this.right.updateInNewLocation();
  64. this.updateInNewLocation();
  65. };
  66.  
  67. AVLTree.prototype.rotateRR = function() {
  68. // the right side is too long => rotate from the right (_not_ rightwards)
  69. var nodeBefore = this.node;
  70. var elementsBefore = this.elements;
  71. var leftBefore = this.left;
  72. this.node = this.right.node;
  73. this.elements = this.right.elements;
  74. this.left = this.right;
  75. this.right = this.right.right;
  76. this.left.right = this.left.left;
  77. this.left.left = leftBefore;
  78. this.left.node = nodeBefore;
  79. this.left.elements = elementsBefore;
  80. this.left.updateInNewLocation();
  81. this.updateInNewLocation();
  82. };
  83.  
  84. AVLTree.prototype.updateInNewLocation = function() {
  85. this.getDepthFromChildren();
  86. };
  87.  
  88. AVLTree.prototype.getDepthFromChildren = function() {
  89. this.depth = this.node == null ? 0 : 1;
  90. if (this.left != null) {
  91. this.depth = this.left.depth + 1;
  92. }
  93. if (this.right != null && this.depth <= this.right.depth) {
  94. this.depth = this.right.depth + 1;
  95. }
  96. };
  97.  
  98. AVLTree.prototype.compare = function(n1, n2) {
  99. v1 = n1[this.attr];
  100. v2 = n2[this.attr];
  101. if (v1 == v2) {
  102. return 0;
  103. }
  104. if (v1 < v2) {
  105. return -1;
  106. }
  107. return 1;
  108. };
  109.  
  110. AVLTree.prototype.add = function(n) {
  111. var o = this.compare(n, this.node);
  112. if (o == 0) {
  113. this.elements.push(n);
  114. return false;
  115. }
  116.  
  117. var ret = false;
  118. if (o == -1) {
  119. if (this.left == null) {
  120. this.left = new AVLTree(n, this.attr);
  121. ret = true;
  122. } else {
  123. ret = this.left.add(n);
  124. if (ret) {
  125. this.balance();
  126. }
  127. }
  128. } else if (o == 1) {
  129. if (this.right == null) {
  130. this.right = new AVLTree(n, this.attr);
  131. ret = true;
  132. } else {
  133. ret = this.right.add(n);
  134. if (ret) {
  135. this.balance();
  136. }
  137. }
  138. }
  139.  
  140. if (ret) {
  141. this.getDepthFromChildren();
  142. }
  143. return ret;
  144. };
  145.  
  146. // Given the beginning of a value, return the elements if there's a match
  147. AVLTree.prototype.findBest = function(value) {
  148. var substr = this.node[this.attr].substr(0, value.length).toLowerCase();
  149. var value = value.toLowerCase();
  150.  
  151. if (value < substr) {
  152. if (this.left != null) {
  153. return this.left.findBest(value);
  154. }
  155. return [];
  156. }
  157. else if (value > substr) {
  158. if (this.right != null) {
  159. return this.right.findBest(value);
  160. }
  161. return [];
  162. }
  163. return this.elements;
  164. }
Add Comment
Please, Sign In to add comment