C# 红黑二叉树,最好的方式走回根?
我正在建造一棵红黑二叉树。我看到的一个问题是在旋转中,并向后移动到父节点,以在旋转后发现黑-红冲突。我不想在树中再次搜索最后一个节点,所以我已经开始为每个节点使用一个返回指针。我不确定我的大脑是否被炸了,我没有正确地思考这个问题,但是如果我必须再次走到树上才能找到:C# 红黑二叉树,最好的方式走回根?,c#,algorithm,tree,C#,Algorithm,Tree,我正在建造一棵红黑二叉树。我看到的一个问题是在旋转中,并向后移动到父节点,以在旋转后发现黑-红冲突。我不想在树中再次搜索最后一个节点,所以我已经开始为每个节点使用一个返回指针。我不确定我的大脑是否被炸了,我没有正确地思考这个问题,但是如果我必须再次走到树上才能找到: if (node.left or .right = current) [which gives me a grandparent] 我不是真的将插入时间增加到了最坏的情况‘Log2(n^n-1)+C’吗 c是常数时间等于的 不过我
if (node.left or .right = current) [which gives me a grandparent]
我不是真的将插入时间增加到了最坏的情况‘Log2(n^n-1)+C’吗
c是常数时间等于的
不过我可以想象,后面的指针要便宜得多。尽管在旋转时重新连接有点棘手,尽管不是那么难。所以,从本质上说,我不是在增加固定时间,而不是以指数方式增加时间吗?使用系统;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace RedBlackTree
{
class RBTree
{
public class node {
public node right, left, next, back,last;//for traversing the
public int id;//for regular implementation
int day, month, year;//for root @ weeks
int hour, min;//for shipment times
byte amPm = 0;//for shipment times
public char color = 'r';//color of node
public Object data;//needed data of node
}
Queue<node> q = new Queue<node>();
node head, tail, isRoot;
node weeks, soNum, custByName;//main roots when customized
node root = null;//for regular insert
static Boolean allIsoff = false;
//regular insert
public void printRoot() {
MessageBox.Show(root.id.ToString());
}
public void insert(int key, Object info) {
allIsoff = false;
node child = new node();
child.id = key;
child.data = info;
if(root == null){
root = child;
child.color = 'b';
return;
}//end root is null
//setup parent and grandParent nodes
node parent = null;
node grandParent = null;
node GGparent = null;
addNode(child, root, parent, grandParent,GGparent);
}//end insert
//for regular insertion
private void addNode(node child, node current, node parent, node grandParent,node greatGparent){
Boolean isTrue = false;//for child and current
Boolean theRest = false;//for current and parent
if(current.id == child.id){
current.data = child.data;
return;
}
if(current.id > child.id ){//going left
if (current.left == null)
{
current.left = child;//add child to the left
isTrue = isRed(current,child);
}
else {//continue left
addNode(child, current.left, current, parent,grandParent);
}
}//end going left
else if (current.id < child.id) {//going right
if (current.right == null)
{
current.right = child;
isTrue = isRed(current, child);
}
else {//continue right
addNode(child, current.right, current, parent,grandParent);
}
}//end going right
if (isTrue == false && allIsoff == false)//then check current and parent
{
theRest = isRed(current, parent);
System.Diagnostics.Debug.WriteLine(current.id+" "+parent.id);
}//end isTrue
if(isTrue || theRest){//if there is a red clash
if (isTrue) {
if (checkUncle(current, parent))
{
repaint(parent);
isTrue = false;
}
else
{
//rotate
if (current.id > child.id)
{//left of parent
if (parent != null)
{
if (parent.left == current)//P is left of Grandparent
{
System.Diagnostics.Debug.WriteLine("T1.A");
current.color = 'b';
parent.color = 'r';
rotateRight(current, parent, grandParent);
allIsoff = true;
return;
}
else
{//P is Right of Grandparent
System.Diagnostics.Debug.WriteLine("T1.B");
child.color = 'b';
parent.color = 'r';
rotateRight(child,current,parent);
rotateLeft(parent,child,grandParent);
allIsoff = true;
return;
}
}//endif P != null
}//end if current > child
else {//child is right of current
if (parent.left == current)//parent is left of grandparent
{
System.Diagnostics.Debug.WriteLine("T1.C");
rotateLeft(current, child, parent);
child.color = 'b';
parent.color = 'r';
rotateRight(child, parent, grandParent);
allIsoff = true;
return;
}
else
{ //parent is right of grandparent
System.Diagnostics.Debug.WriteLine("T1.D");
rotateLeft(parent, current, grandParent);
current.color = 'b';
parent.color = 'r';
allIsoff = true;
return;
}
}//end else
}//END ELSE
}//end isTure
else if (theRest) {
if (checkUncle(parent, grandParent))
{
repaint(grandParent);
theRest = false;
}
else
{
//rotate
if (parent.id > current.id)
{ //left of parent
if (grandParent != null)
{
if (grandParent.left == parent)//P is left of Grandparent
{
System.Diagnostics.Debug.WriteLine("T2.A");
grandParent.color = 'r';
parent.color = 'b';
rotateRight(parent,grandParent,greatGparent);
allIsoff = true;
return;
}
else
{//P is Right of Grandparent
System.Diagnostics.Debug.WriteLine("T2.B");
rotateRight(current, parent, grandParent);
grandParent.color = 'r';
current.color = 'b';
rotateLeft(grandParent, current, greatGparent);
allIsoff = true;
return;
}
}//what if grandParent is null????????
else {
if (parent.right.color == 'b')//code should never execute
{
System.Diagnostics.Debug.WriteLine("T2.C");
current.color = 'b';
rotateRight(current,parent,null);
allIsoff = true;
return;
}
}//end else for root rotation
}
else {//right of parent
if (grandParent != null)
{
if (grandParent.left == parent)//P is left of Grandparent
{
System.Diagnostics.Debug.WriteLine("T2.D");
rotateLeft(parent,current,greatGparent);
current.color = 'b';
grandParent.color = 'r';
rotateRight(current,grandParent,greatGparent);
allIsoff = true;
return;
}
else
{//P is Right of Grandparent
System.Diagnostics.Debug.WriteLine("T2.E");
rotateLeft(grandParent,parent,greatGparent);
grandParent.color = 'r';
parent.color = 'b';
allIsoff = true;
return;
}
}//what if grandParent is null????????
else
{
if (parent.left.color == 'b')//CODE SHOULD NEVER EXECUTE
{
System.Diagnostics.Debug.WriteLine("T2.F");
current.color = 'b';
rotateLeft(parent,current,null);
allIsoff = true;
return;
}
}//end else for root rotation
}
}//END ELSE
}
}//end red clash check
}//end addNode
public void repaint(node grandparent) {
grandparent.right.color = 'b';
grandparent.left.color = 'b';
grandparent.color = 'r';
if (grandparent == root) {
grandparent.color = 'b';
}
}
public Boolean checkUncle(node parent, node grandparent) {
if (parent != null) {
if (grandparent != null) {
if (grandparent.left == parent)
{
if (grandparent.right != null)
{
if (grandparent.right.color.Equals('r'))
{
return true;
}
}
}
else {
if (grandparent.left != null)
{
if (grandparent.left.color.Equals('r'))
{
return true;
}
}
}
}
}
return false;
}//end check uncle
public Boolean isRed(node a, node b) {
if (a != null)
{
if (a.color.Equals('r'))
{
if (b != null)
{
if (b.color.Equals('r'))
{
return true;
}
}
}
}
return false;
}
//inorder traversal for testing
String inorder = "";
public void doTraversal() {
inorderT(root);
}
public void inorderT(node current) {
if (current != null)
{
inorder += current.id.ToString() + "(" + current.color.ToString() + "),";
inorderT(current.left);
inorderT(current.right);
}
}//end inorderT
public String getInorder() {
return inorder;
}
public void resetInorder() {
inorder = "";
}
public void clearTree() {
root = null;
}
//end methods for inorder traversal for testing
public void breadthFirst() {
}
public void rotateLeft(node p, node q, node grand) {
if (grand != null)
{
System.Diagnostics.Debug.WriteLine("hereRotateLeft !null");
p.right = q.left;
q.left = p;
if (grand.right == p)
{
grand.right = q;
}
else { grand.left = q; }
}
else {
System.Diagnostics.Debug.WriteLine("hereRotateLeft else");
p.right = q.left;
q.left = p;
root = q;
}
}//end left rotation
public void rotateRight(node p, node q, node grand)
{
if (grand != null)
{
System.Diagnostics.Debug.WriteLine("hereRotateRight not null");
q.left = p.right;
p.right = q;
if (grand.right == q)
{
grand.right = p;
}
else { grand.left = p; }
}
else
{
System.Diagnostics.Debug.WriteLine("hereRotateRight else");
q.left = p.right;
p.right = q;
root = p;
}
}//end left rotation
public void addLotForward() {
for (int l = 0; l < 12; l++ )
{
insert(l, "");
}
}
// Queue<node> q = new Queue<node>();
//following code is for testing, breadth first search
int[] arr = new int[]{1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384};
int i =0;
int b = 0;
int w = 0;
int keeper = 0;
public void BFS()
{
q.Enqueue(root);
while (q.Count > 0)
{
node n = q.Dequeue();
if (i == arr[b])
{
System.Diagnostics.Debug.Write("\r\n"+"("+n.id+""+n.color+")");
b++;
i =0 ;
}
else {
System.Diagnostics.Debug.Write("(" + n.id + "" + n.color + ")");
}
i++;
if (n.id != -1)
{
w = 0;
if (n.left != null)
{
q.Enqueue(n.left);
}
else
{
node c = new node();
c.id = -1;
c.color = 'b';
q.Enqueue(c);
}
if (n.right != null)
{
q.Enqueue(n.right);
}
else
{
node c = new node();
c.id = -1;
c.color = 'b';
q.Enqueue(c);
}
}
else {
w++;
node c = new node();
c.id = -1;
c.color = 'b';
q.Enqueue(c);
if (w == arr[b])
{
break;
}
}
}
q.Clear();
w = 0;
i = 0;
b = 0;
System.Diagnostics.Debug.Write("\r\n");
return;
}
}//end main class
}
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
命名空间红黑树
{
类RBTree
{
公共类节点{
公共节点right、left、next、back、last;//用于遍历
public int id;//用于常规实现
int day,month,year;//对于root@weeks
int hour,min;//用于装运时间
字节amPm=0;//用于装运时间
public char color='r';//节点的颜色
公共对象数据;//节点需要的数据
}
队列q=新队列();
节头、节尾、节根;
节点周、soNum、custByName;//自定义时的主根
节点根=null;//用于常规插入
静态布尔allIsoff=false;
//常规插入
public void printRoot(){
Show(root.id.ToString());
}
公共void插入(int键、对象信息){
allIsoff=假;
节点子节点=新节点();
child.id=key;
child.data=info;
if(root==null){
根=子;
child.color='b';
返回;
}//结束根为空
//设置父节点和祖父母节点
节点父节点=null;
节点祖父母=null;
节点GGparent=null;
addNode(子节点、根节点、父节点、祖父母节点、父节点);
}//端部嵌件
//定期插入
私有void addNode(节点子节点、节点当前节点、节点父节点、节点祖父母、节点greatGparent){
布尔isTrue=false;//用于子级和当前
布尔值theRest=false;//用于当前和父级
if(current.id==child.id){
current.data=child.data;
返回;
}
如果(current.id>child.id){//向左走
if(current.left==null)
{
current.left=child;//将child添加到左侧
isTrue=isRed(当前,子级);
}
否则{//继续向左
addNode(子节点、当前节点、左节点、当前节点、父节点、祖父母节点);
}
}//向左转结束
如果(current.idchild.id)
{//父对象的左侧
如果(父项!=null)
{
如果(parent.left==current)//P是祖父母的左边
{
系统、诊断、调试、写入线(“T1.A”);
current.color='b';
parent.color='r';
rotateRight(当前、父母、祖父母);
allIsoff=真;
返回;
}
其他的
{//P是祖父母的权利
System.Diagnostics.Debug.WriteLine(“T1.B”);
child.color='b';
parent.color='r';
rotateRight(子级、当前、父级);
rotateLeft(父母、子女、祖父母);
allIsoff=真;
返回;
}
}//endif P!=null
}//如果当前>子级,则结束
否则{//child是当前
如果(parent.left==current)//父母是祖父母的左边
{
系统.诊断.调试.写入线(“T1.C”);
rotateLeft(当前、子项、父项);
child.color='b';
parent.color='r';
轮换权(儿童、父母、祖父母);