红黑树排序(javascript)

  1.  /**********************************************************/
  2.   /*红黑树(平衡树)排序                                      */
  3.   /**********************************************************/
  4.   var red = 1;
  5.   var black = 0;
  6.   
  7.   //结点
  8.   function RB_Node(val)
  9.   {
  10.       this.left  = null;                  //左结点
  11.       this.right = null;                  //右结点
  12.       this.parent = null;                 //父结点
  13.   
  14.       this.color = red;                   //结点的颜色
  15.        
  16.       this.value = val;                  //值结点 
  17.       
  18.       //取得叔父结点
  19.       this.Uncle = function()
  20.       {
  21.         if(this.parent == this.Grandpa().left) return this.Grandpa().right;
  22.        
  23.         return this.Grandpa().left;
  24.       }
  25.       
  26.       //取得祖父结点
  27.       this.Grandpa = function()
  28.       {
  29.         return this.parent.parent;
  30.       }
  31.   }
  32.   
  33.   //树
  34.   function RB_Tree()
  35.   {
  36.     this.header = null;          //头结点
  37.     this.output_string = "";
  38.    
  39.     //插入结点
  40.     this.InsertNode = function(val)
  41.     {
  42.         var node = new RB_Node(val);
  43.         var target_pos = this.header;
  44.             
  45.         var parent = null;
  46.         var be_in_left = true;
  47.         
  48.         //查找插入位置
  49.         while(null != target_pos)
  50.         {
  51.             parent = target_pos;
  52.             if(this.compare(node,target_pos))   //插入右树
  53.             {
  54.                 target_pos = target_pos.right;
  55.                 be_in_left = false;
  56.             }
  57.             else                      //插入左子树
  58.             {
  59.                 target_pos =target_pos.left;
  60.                 be_in_left = true;
  61.             }
  62.         }
  63.     
  64.         node.parent = parent;
  65.         
  66.         if(parent){
  67.             if(be_in_left){
  68.                 //alert(val + "插到" + parent.value + "的左子树");
  69.                 parent.left = node;
  70.             }else{
  71.                 //alert(val + "插到" + parent.value + "的右子树");
  72.                 parent.right = node;
  73.             }
  74.         }
  75.         else{
  76.             this.header = node;
  77.         }
  78.         
  79.         //调整颜色值或结构
  80.         this.adjustPath(node);
  81.     }
  82.     
  83.     this.compare = function(l, r)
  84.     {
  85.         if(parseInt(l.value) > parseInt(r.value))
  86.             return true;
  87.         return false;
  88.     }
  89.     
  90.     this.adjustPath = function(node)
  91.     {
  92.         var w = null;
  93.         var s = "node =" + node + "; header = " + this.header + "node == header is " + (node == this.header);
  94.         s +=  "/r/n node.value=" + node.value + ", node.parent = " + node.parent;
  95.         if(node.parent != null)
  96.             s+= "node.parent.color = " + node.parent.color;
  97.             
  98.         //alert(s);
  99.        
  100.         while(node != this.header && node.parent.color == red)
  101.         {
  102.             //alert("going...");
  103.                   //如果为左子树
  104.           if(node.parent == node.Grandpa().left)
  105.           {
  106.             //alert("going...1a");
  107.             w = node.Uncle();
  108.             if(w != null && red == w.color)   //如果叔父结点为红色的,则只需将叔父和父结点置为黑色,祖父结点置为红色,然后祖父结点的父结点可能为红色,则违反了规则,需要继续调整
  109.             {
  110.                 //alert("going...1b");
  111.                 w.color = black;
  112.                 node.parent.color = black;
  113.                 node.Grandpa().color = red;
  114.                 node = node.Grandpa();
  115.             }
  116.             else
  117.             {
  118.                 //如果node为右子树
  119.                 if(node == node.parent.right)
  120.                 {
  121.                     //alert("going...1c");
  122.                     node = node.parent;
  123.                     
  124.                     //alert("before roate_left node = " + node.value + " node.parent = " + node.parent.value + " node.Grandpa().value = "+node.Grandpa().value)
  125.                     this.rotate_left(node);
  126.                    // alert("after roate_left node = " + node.value + " node.parent = " + node.parent.value + " node.Grandpa().value = "+node.Grandpa().value)
  127.                 }
  128.                 
  129.                 //alert("going...1d");
  130.                 node.parent.color = black;
  131.                 node.Grandpa().color = red;
  132.                 //alert("before roate_right node = " + node.value + " node.Grandpa() = " + node.Grandpa().value)
  133.                 this.rotate_right(node.Grandpa());
  134.                 //alert("after roate_left node = " + node.value + " node.parent = " + node.parent.value)
  135.             }
  136.           }
  137.           else      //为右子树
  138.           {
  139.             //alert("going...2a");
  140.             
  141.             w = node.Uncle();
  142.             
  143.             if(w != null && red == w.color)   //如果叔父结点为红色的,则只需将叔父和父结点置为黑色,祖父结点置为红色,然后祖父结点的父结点可能为红色,则违反了规则,需要继续调整
  144.             {
  145.                 //alert("going...2b");
  146.                 w.color = black;
  147.                 node.parent.color = black;
  148.                 node.Grandpa().color = red;
  149.                 node = node.Grandpa();
  150.             }
  151.             else
  152.             {
  153.                 //如果node为右子树
  154.                 if(node == node.parent.left)
  155.                 {
  156.                     //alert("going...2c");
  157.                     node = node.parent;
  158.                     this.rotate_right(node);
  159.                 }
  160.                 
  161.                 //alert("going...2d");
  162.                 
  163.                 node.parent.color = black;
  164.                 node.Grandpa().color = red;
  165.                 this.rotate_left(node.Grandpa());
  166.             }
  167.           }
  168.         }
  169.         
  170.         this.header.color = black;
  171.     }
  172.     
  173.     //输出
  174.     this.Traverse = function()
  175.     {
  176.         this.traverse_tree(this.header);
  177.     }
  178.     
  179.     this.traverse_tree = function(node)
  180.     {
  181.         if(node == nullreturn;
  182.         
  183.         this.traverse_tree(node.left);
  184.         
  185.         this.output_string += node.value + " ";
  186.         
  187.         this.traverse_tree(node.right);
  188.     }
  189.     
  190.     //左旋转结点
  191.     this.rotate_left = function(node)
  192.     {
  193.         var parent = node.parent;
  194.         var right = node.right;
  195.         
  196.         //alert("in rotate_left " + right);// + " right.left" + right.left + "right.right" + right.right);
  197.         
  198.         var rleft = right.left;
  199.         
  200.         
  201.         
  202.         //将node子树作为右子树的左子树,并将右子树的左子树做为node的右子树
  203.         right.left = node;
  204.         node.parent = right;
  205.         node.right = rleft;
  206.         
  207.         //将右子树代替node
  208.         if(parent != null)
  209.         {
  210.             if(node == parent.left)  //如果原来是左子树
  211.                parent.left = right;
  212.             else
  213.                parent.right = right;
  214.         }
  215.         right.parent = parent;
  216.         
  217.         //将右子树的原左子树挂到原root下
  218.         if(rleft)
  219.             rleft.parent = node;
  220.         if(parent == null)
  221.             this.header = right;
  222.     }
  223.     
  224.     
  225.     //右旋转结点
  226.     this.rotate_right = function(node)
  227.     {
  228.         var parent = node.parent;
  229.         var left = node.left;
  230.         //alert("in rotate_right: node.value" + node.value + " left = " + left);// + " right.left" + right.left + "right.right" + right.right);
  231.         var lright = left.right;
  232.         
  233.         //将node挂到左子树的右子树
  234.         left.right = node;
  235.         node.parent = left;
  236.         node.left = lright;
  237.         //将左子树代替node
  238.         if(parent)
  239.             if(parent.left== node)
  240.                 parent.left = left;
  241.             else
  242.                 parent.right = left;
  243.         left.parent = parent;
  244.         //将左子树的原右子树挂到原root下
  245.         if(lright)
  246.             lright.parent = node;
  247.         if(parent == null)
  248.                 this.header = left;
  249.     }
  250.   }
  251.   /***********************************************************/
测试代码
  1. var tree = new RB_Tree();
  2. //插入
  3. for(var i = 10; i > 0; i--)
  4.     tree.InsertNode(Math.ceil(Math.random() * 100));
  5. //结束
  6. tree.Traverse();
  7. alert("output:" + tree.output_string);

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值