BinaryTree.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. define("dojox/collections/BinaryTree", ["dojo/_base/kernel", "dojo/_base/array", "./_base"], function(dojo, darray, dxc){
  2. /*=====
  3. var dxc = dojox.collections;
  4. =====*/
  5. dxc.BinaryTree=function(data){
  6. function node(data, rnode, lnode){
  7. this.value=data||null;
  8. this.right=rnode||null;
  9. this.left=lnode||null;
  10. this.clone=function(){
  11. var c=new node();
  12. if(this.value.value){
  13. c.value=this.value.clone();
  14. }else{
  15. c.value=this.value;
  16. }
  17. if(this.left!=null){
  18. c.left=this.left.clone();
  19. }
  20. if(this.right!=null){
  21. c.right=this.right.clone();
  22. }
  23. return c;
  24. }
  25. this.compare=function(n){
  26. if(this.value>n.value){ return 1; }
  27. if(this.value<n.value){ return -1; }
  28. return 0;
  29. }
  30. this.compareData=function(d){
  31. if(this.value>d){ return 1; }
  32. if(this.value<d){ return -1; }
  33. return 0;
  34. }
  35. }
  36. function inorderTraversalBuildup(current, a){
  37. if(current){
  38. inorderTraversalBuildup(current.left, a);
  39. a.push(current.value);
  40. inorderTraversalBuildup(current.right, a);
  41. }
  42. }
  43. function preorderTraversal(current, sep){
  44. var s="";
  45. if (current){
  46. s=current.value.toString() + sep;
  47. s+=preorderTraversal(current.left, sep);
  48. s+=preorderTraversal(current.right, sep);
  49. }
  50. return s;
  51. }
  52. function inorderTraversal(current, sep){
  53. var s="";
  54. if (current){
  55. s=inorderTraversal(current.left, sep);
  56. s+=current.value.toString() + sep;
  57. s+=inorderTraversal(current.right, sep);
  58. }
  59. return s;
  60. }
  61. function postorderTraversal(current, sep){
  62. var s="";
  63. if (current){
  64. s=postorderTraversal(current.left, sep);
  65. s+=postorderTraversal(current.right, sep);
  66. s+=current.value.toString() + sep;
  67. }
  68. return s;
  69. }
  70. function searchHelper(current, data){
  71. if(!current){ return null; }
  72. var i=current.compareData(data);
  73. if(i==0){ return current; }
  74. if(i>0){ return searchHelper(current.left, data); }
  75. else{ return searchHelper(current.right, data); }
  76. }
  77. this.add=function(data){
  78. var n=new node(data);
  79. var i;
  80. var current=root;
  81. var parent=null;
  82. while(current){
  83. i=current.compare(n);
  84. if(i==0){ return; }
  85. parent=current;
  86. if(i>0){ current=current.left; }
  87. else{ current=current.right; }
  88. }
  89. this.count++;
  90. if(!parent){
  91. root=n;
  92. }else{
  93. i=parent.compare(n);
  94. if(i>0){
  95. parent.left=n;
  96. }else{
  97. parent.right=n;
  98. }
  99. }
  100. };
  101. this.clear=function(){
  102. root=null;
  103. this.count=0;
  104. };
  105. this.clone=function(){
  106. var c=new dxc.BinaryTree();
  107. var itr=this.getIterator();
  108. while(!itr.atEnd()){
  109. c.add(itr.get());
  110. }
  111. return c;
  112. };
  113. this.contains=function(data){
  114. return this.search(data) != null;
  115. };
  116. this.deleteData=function(data){
  117. var current=root;
  118. var parent=null;
  119. var i=current.compareData(data);
  120. while(i!=0&&current!=null){
  121. if(i>0){
  122. parent=current;
  123. current=current.left;
  124. }else if(i<0){
  125. parent=current;
  126. current=current.right;
  127. }
  128. i=current.compareData(data);
  129. }
  130. if(!current){ return; }
  131. this.count--;
  132. if(!current.right){
  133. if(!parent){
  134. root=current.left;
  135. }else{
  136. i=parent.compare(current);
  137. if(i>0){ parent.left=current.left; }
  138. else if(i<0){ parent.right=current.left; }
  139. }
  140. }
  141. else if(!current.right.left){
  142. if(!parent){
  143. root=current.right;
  144. }else{
  145. i=parent.compare(current);
  146. if(i>0){ parent.left=current.right; }
  147. else if(i<0){ parent.right=current.right; }
  148. }
  149. }
  150. else{
  151. var leftmost=current.right.left;
  152. var lmParent=current.right;
  153. while(leftmost.left!=null){
  154. lmParent=leftmost;
  155. leftmost=leftmost.left;
  156. }
  157. lmParent.left=leftmost.right;
  158. leftmost.left=current.left;
  159. leftmost.right=current.right;
  160. if(!parent){
  161. root=leftmost;
  162. }else{
  163. i=parent.compare(current);
  164. if(i>0){ parent.left=leftmost; }
  165. else if(i<0){ parent.right=leftmost; }
  166. }
  167. }
  168. };
  169. this.getIterator=function(){
  170. var a=[];
  171. inorderTraversalBuildup(root, a);
  172. return new dxc.Iterator(a);
  173. };
  174. this.search=function(data){
  175. return searchHelper(root, data);
  176. };
  177. this.toString=function(order, sep){
  178. if(!order){ order=dxc.BinaryTree.TraversalMethods.Inorder; }
  179. if(!sep){ sep=","; }
  180. var s="";
  181. switch(order){
  182. case dxc.BinaryTree.TraversalMethods.Preorder:
  183. s=preorderTraversal(root, sep);
  184. break;
  185. case dxc.BinaryTree.TraversalMethods.Inorder:
  186. s=inorderTraversal(root, sep);
  187. break;
  188. case dxc.BinaryTree.TraversalMethods.Postorder:
  189. s=postorderTraversal(root, sep);
  190. break;
  191. };
  192. if(s.length==0){ return ""; }
  193. else{ return s.substring(0, s.length - sep.length); }
  194. };
  195. this.count=0;
  196. var root=this.root=null;
  197. if(data){
  198. this.add(data);
  199. }
  200. }
  201. dxc.BinaryTree.TraversalMethods={
  202. Preorder: 1, Inorder: 2, Postorder: 3
  203. };
  204. return dxc.BinaryTree;
  205. });