- /**********************************************************/
- /*红黑树(平衡树)排序 */
- /**********************************************************/
- var red = 1;
- var black = 0;
- //结点
- function RB_Node(val)
- {
- this.left = null; //左结点
- this.right = null; //右结点
- this.parent = null; //父结点
- this.color = red; //结点的颜色
- this.value = val; //值结点
- //取得叔父结点
- this.Uncle = function()
- {
- if(this.parent == this.Grandpa().left) return this.Grandpa().right;
- return this.Grandpa().left;
- }
- //取得祖父结点
- this.Grandpa = function()
- {
- return this.parent.parent;
- }
- }
- //树
- function RB_Tree()
- {
- this.header = null; //头结点
- this.output_string = "";
- //插入结点
- this.InsertNode = function(val)
- {
- var node = new RB_Node(val);
- var target_pos = this.header;
- var parent = null;
- var be_in_left = true;
- //查找插入位置
- while(null != target_pos)
- {
- parent = target_pos;
- if(this.compare(node,target_pos)) //插入右树
- {
- target_pos = target_pos.right;
- be_in_left = false;
- }
- else //插入左子树
- {
- target_pos =target_pos.left;
- be_in_left = true;
- }
- }
- node.parent = parent;
- if(parent){
- if(be_in_left){
- //alert(val + "插到" + parent.value + "的左子树");
- parent.left = node;
- }else{
- //alert(val + "插到" + parent.value + "的右子树");
- parent.right = node;
- }
- }
- else{
- this.header = node;
- }
- //调整颜色值或结构
- this.adjustPath(node);
- }
- this.compare = function(l, r)
- {
- if(parseInt(l.value) > parseInt(r.value))
- return true;
- return false;
- }
- this.adjustPath = function(node)
- {
- var w = null;
- var s = "node =" + node + "; header = " + this.header + "node == header is " + (node == this.header);
- s += "/r/n node.value=" + node.value + ", node.parent = " + node.parent;
- if(node.parent != null)
- s+= "node.parent.color = " + node.parent.color;
- //alert(s);
- while(node != this.header && node.parent.color == red)
- {
- //alert("going...");
- //如果为左子树
- if(node.parent == node.Grandpa().left)
- {
- //alert("going...1a");
- w = node.Uncle();
- if(w != null && red == w.color) //如果叔父结点为红色的,则只需将叔父和父结点置为黑色,祖父结点置为红色,然后祖父结点的父结点可能为红色,则违反了规则,需要继续调整
- {
- //alert("going...1b");
- w.color = black;
- node.parent.color = black;
- node.Grandpa().color = red;
- node = node.Grandpa();
- }
- else
- {
- //如果node为右子树
- if(node == node.parent.right)
- {
- //alert("going...1c");
- node = node.parent;
- //alert("before roate_left node = " + node.value + " node.parent = " + node.parent.value + " node.Grandpa().value = "+node.Grandpa().value)
- this.rotate_left(node);
- // alert("after roate_left node = " + node.value + " node.parent = " + node.parent.value + " node.Grandpa().value = "+node.Grandpa().value)
- }
- //alert("going...1d");
- node.parent.color = black;
- node.Grandpa().color = red;
- //alert("before roate_right node = " + node.value + " node.Grandpa() = " + node.Grandpa().value)
- this.rotate_right(node.Grandpa());
- //alert("after roate_left node = " + node.value + " node.parent = " + node.parent.value)
- }
- }
- else //为右子树
- {
- //alert("going...2a");
- w = node.Uncle();
- if(w != null && red == w.color) //如果叔父结点为红色的,则只需将叔父和父结点置为黑色,祖父结点置为红色,然后祖父结点的父结点可能为红色,则违反了规则,需要继续调整
- {
- //alert("going...2b");
- w.color = black;
- node.parent.color = black;
- node.Grandpa().color = red;
- node = node.Grandpa();
- }
- else
- {
- //如果node为右子树
- if(node == node.parent.left)
- {
- //alert("going...2c");
- node = node.parent;
- this.rotate_right(node);
- }
- //alert("going...2d");
- node.parent.color = black;
- node.Grandpa().color = red;
- this.rotate_left(node.Grandpa());
- }
- }
- }
- this.header.color = black;
- }
- //输出
- this.Traverse = function()
- {
- this.traverse_tree(this.header);
- }
- this.traverse_tree = function(node)
- {
- if(node == null) return;
- this.traverse_tree(node.left);
- this.output_string += node.value + " ";
- this.traverse_tree(node.right);
- }
- //左旋转结点
- this.rotate_left = function(node)
- {
- var parent = node.parent;
- var right = node.right;
- //alert("in rotate_left " + right);// + " right.left" + right.left + "right.right" + right.right);
- var rleft = right.left;
- //将node子树作为右子树的左子树,并将右子树的左子树做为node的右子树
- right.left = node;
- node.parent = right;
- node.right = rleft;
- //将右子树代替node
- if(parent != null)
- {
- if(node == parent.left) //如果原来是左子树
- parent.left = right;
- else
- parent.right = right;
- }
- right.parent = parent;
- //将右子树的原左子树挂到原root下
- if(rleft)
- rleft.parent = node;
- if(parent == null)
- this.header = right;
- }
- //右旋转结点
- this.rotate_right = function(node)
- {
- var parent = node.parent;
- var left = node.left;
- //alert("in rotate_right: node.value" + node.value + " left = " + left);// + " right.left" + right.left + "right.right" + right.right);
- var lright = left.right;
- //将node挂到左子树的右子树
- left.right = node;
- node.parent = left;
- node.left = lright;
- //将左子树代替node
- if(parent)
- if(parent.left== node)
- parent.left = left;
- else
- parent.right = left;
- left.parent = parent;
- //将左子树的原右子树挂到原root下
- if(lright)
- lright.parent = node;
- if(parent == null)
- this.header = left;
- }
- }
- /***********************************************************/
测试代码
- var tree = new RB_Tree();
- //插入
- for(var i = 10; i > 0; i--)
- tree.InsertNode(Math.ceil(Math.random() * 100));
- //结束
- tree.Traverse();
- alert("output:" + tree.output_string);