红黑树插入修复错误
我有一个关于在 C# 中插入红黑树的家庭作业问题。我编写了下面的代码,程序在添加前 3 个数字时没有任何问题。当我尝试添加第四个数字时,出现 NullReferenceException。我试图解决这个错误两天,但我无法弄清楚。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Algoritmalar3b
{
class rbtNode
{
public int? key;
public char? color;
public rbtNode left, right, p;
public rbtNode(int? key, char? color, rbtNode left, rbtNode right, rbtNode p)
{
this.key = key;
this.color = color;
this.left = left;
this.right = right;
this.p = p;
}
}
class Program
{
static rbtNode Tnil = new rbtNode(null, 'B', null, null, null);
static void Main(string[] args)
{
rbtNode root = new rbtNode(null, 'B', Tnil, Tnil, null);
RB_Insert(root, 7);
RB_Insert(root, 3);
RB_Insert(root, 89);
RB_Insert(root, 4);
RB_Insert(root, 9);
RB_Insert(root, 15);
RB_Insert(root, 35);
RB_Insert(root, 8);
RB_Insert(root, 24);
preOrderWalk(root);
}
static void RB_Insert(rbtNode T, int? deger)
{
rbtNode z = new rbtNode(deger, null, Tnil, Tnil, null);
if (T.key == null)
T.key = deger;
else
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
y = Tnil;
rbtNode x = new rbtNode(null, null, Tnil, Tnil, null);
x = T;
while (x != Tnil)
{
y = x;
if (z.key < x.key)
x = x.left;
else
x = x.right;
}
z.p = y;
if (y == Tnil)
T = z;
else if (z.key < y.key)
y.left = z;
else
y.right = z;
z.left = Tnil;
z.right = Tnil;
z.color = 'R';
RB_Insert_Fixup(T, z);
}
}
static void RB_Insert_Fixup(rbtNode T, rbtNode z)
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
while (z.p.color == 'R')
{
if (z.p == z.p.p.left)
{
y = z.p.p.right;
if (y.color == 'R')
{
z.p.color = 'B';
y.color = 'B';
z.p.p.color = 'R';
z = z.p.p;
}
else if (z == z.p.right)
{
z = z.p;
Left_Rotate(T, z);
z.p.color = 'B';
z.p.p.color = 'R';
Right_Rotate(T, z.p.p);
}
}
else
{
y = z.p.p.left;
if (y.color == 'R')
{
z.p.color = 'B';
y.color = 'B';
z.p.p.color = 'R';
z = z.p.p;
}
else if (z == z.p.left)
{
z = z.p;
Left_Rotate(T, z);
z.p.color = 'B';
z.p.p.color = 'R';
Right_Rotate(T, z.p.p);
}
}
}
T.color = 'B';
}
static void Left_Rotate(rbtNode T, rbtNode x)
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
y = x.right;
x.right = y.left;
if (y.left != Tnil)
y.left.p = x;
y.p = x.p;
if (x.p == Tnil)
T = y;
else if (x == x.p.left)
x.p.left = y;
else
x.p.right = y;
y.left = x;
x.p = y;
}
static void Right_Rotate(rbtNode T, rbtNode x)
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
y = x.left;
x.left = y.right;
if (y.right != null)
y.right.p = x;
y.p = x.p;
if (x.p == null)
T = y;
else if (x == x.p.right)
x.p.right = y;
else
x.p.left = y;
y.right = x;
x.p = y;
}
static void preOrderWalk(rbtNode T)
{
if (T.color == 'B')
Console.WriteLine("-{0}", T.key);
else
Console.WriteLine("{0}", T.key);
if (T.left != null)
preOrderWalk(T.left);
if (T.right != null)
preOrderWalk(T.right);
}
}
}
I have a homework problem about inserting into red-black trees in c#. I wrote the code below and the program works without any problems for adding first 3 numbers. When I try to add the 4th number, I get a NullReferenceException. I'm trying to solve the error for 2 days but I can't figure it out.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Algoritmalar3b
{
class rbtNode
{
public int? key;
public char? color;
public rbtNode left, right, p;
public rbtNode(int? key, char? color, rbtNode left, rbtNode right, rbtNode p)
{
this.key = key;
this.color = color;
this.left = left;
this.right = right;
this.p = p;
}
}
class Program
{
static rbtNode Tnil = new rbtNode(null, 'B', null, null, null);
static void Main(string[] args)
{
rbtNode root = new rbtNode(null, 'B', Tnil, Tnil, null);
RB_Insert(root, 7);
RB_Insert(root, 3);
RB_Insert(root, 89);
RB_Insert(root, 4);
RB_Insert(root, 9);
RB_Insert(root, 15);
RB_Insert(root, 35);
RB_Insert(root, 8);
RB_Insert(root, 24);
preOrderWalk(root);
}
static void RB_Insert(rbtNode T, int? deger)
{
rbtNode z = new rbtNode(deger, null, Tnil, Tnil, null);
if (T.key == null)
T.key = deger;
else
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
y = Tnil;
rbtNode x = new rbtNode(null, null, Tnil, Tnil, null);
x = T;
while (x != Tnil)
{
y = x;
if (z.key < x.key)
x = x.left;
else
x = x.right;
}
z.p = y;
if (y == Tnil)
T = z;
else if (z.key < y.key)
y.left = z;
else
y.right = z;
z.left = Tnil;
z.right = Tnil;
z.color = 'R';
RB_Insert_Fixup(T, z);
}
}
static void RB_Insert_Fixup(rbtNode T, rbtNode z)
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
while (z.p.color == 'R')
{
if (z.p == z.p.p.left)
{
y = z.p.p.right;
if (y.color == 'R')
{
z.p.color = 'B';
y.color = 'B';
z.p.p.color = 'R';
z = z.p.p;
}
else if (z == z.p.right)
{
z = z.p;
Left_Rotate(T, z);
z.p.color = 'B';
z.p.p.color = 'R';
Right_Rotate(T, z.p.p);
}
}
else
{
y = z.p.p.left;
if (y.color == 'R')
{
z.p.color = 'B';
y.color = 'B';
z.p.p.color = 'R';
z = z.p.p;
}
else if (z == z.p.left)
{
z = z.p;
Left_Rotate(T, z);
z.p.color = 'B';
z.p.p.color = 'R';
Right_Rotate(T, z.p.p);
}
}
}
T.color = 'B';
}
static void Left_Rotate(rbtNode T, rbtNode x)
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
y = x.right;
x.right = y.left;
if (y.left != Tnil)
y.left.p = x;
y.p = x.p;
if (x.p == Tnil)
T = y;
else if (x == x.p.left)
x.p.left = y;
else
x.p.right = y;
y.left = x;
x.p = y;
}
static void Right_Rotate(rbtNode T, rbtNode x)
{
rbtNode y = new rbtNode(null, null, Tnil, Tnil, null);
y = x.left;
x.left = y.right;
if (y.right != null)
y.right.p = x;
y.p = x.p;
if (x.p == null)
T = y;
else if (x == x.p.right)
x.p.right = y;
else
x.p.left = y;
y.right = x;
x.p = y;
}
static void preOrderWalk(rbtNode T)
{
if (T.color == 'B')
Console.WriteLine("-{0}", T.key);
else
Console.WriteLine("{0}", T.key);
if (T.left != null)
preOrderWalk(T.left);
if (T.right != null)
preOrderWalk(T.right);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
看来你在 3 个方面有问题:
当我快速查看 Fixup 方法和其余代码时,我怀疑您可能在错误的位置将 ap(Parent)ref 设置为 null。
作为诊断工具,更改常规属性中的 .p 成员:
我认为您必须允许 _parent=null 但仅在构造函数中。
get/set 成员还为您提供了放置(条件)断点的好位置。
It seems you have problems in 3 areas:
When I take a quick look at the Fixup method and the rest of the code I suspect you may have a p (Parent) ref being null at the wrong point.
As a diagnosis tool, change the .p member in a regular property:
I think you will have to allow _parent=null but only in the constructor.
The get/set members also give you a good spot to place (conditional) breakpoints.
我相信您的 fix_up 功能出了点问题。在 while 循环中添加某些条件,即
此外,您在 while 循环的 else 部分中犯了一个重大错误。更改 LeftRotate 和 RightRotate 函数的顺序,应如下所示:
编辑:您还需要在两个 Rotate 函数中添加更多条件。
I believe you are going a bit wrong in your fix_up function. Add certain conditions in while loop i.e.
Also, you are making a major mistake in the else part of your while loop. Change the order of LeftRotate and RightRotate functions, it should be as follows:
EDIT: you would also need to add a few more conditions in both Rotate functions.