Ссылочная проблема C#

Я беру курс алгоритма в университете, и для одного из моих проектов я хочу реализовать красно-черное дерево в C# (сама реализация не является проектом, еще просто что-то, что я решил принять решение выручить меня).

Мое красно-черное дерево должно содержать строковые ключи, и объект, который я создал для каждого узла, похож на это:

class sRbTreeNode
{
    public sRbTreeNode Parent = null;
    public sRbTreeNode Right = null;
    public sRbTreeNode Left = null;
    public String Color;
    public String Key;

    public sRbTreeNode()
    {
    }

    public sRbTreeNode(String key)
    {
        Key = key;
    }
}

Я уже добавил некоторые основные методы для печати дерева, нахождения корня, минута, ключевая / макс. ключевой (алфавитом), и т.д...

Я испытываю затруднения при вставке узлов (следовательно, создании дерева). Кто бы ни знаком с красно-черными деревьями, знает, что при добавлении узла к одной стороне, Вы, возможно, изменили баланс дерева. Для фиксации этого необходимо "вращаться" вокруг узлов на дереве для балансирования дерева.

Я записал метод RightRotate и LeftRotate в псевдокоде, и затем когда я пытался реализовать его в C#, я столкнулся с набором ссылочных проблем с объектом sRbTreeNode, который что я создал.

Это - псевдокод, который я записал для метода LeftRotate:

LeftRotate(root, node)
    y <- node.Right;
    node.Right <- y.Left;
    if (y.Left != null)
        y.Left.Parent <- node;
    y.Parent <- node.Parent;
    if (node.Parent = null)
        root <- y;
    else
        if (node = node.Parent.Left)
            node.Parent.Left = y;
        else
            node.Parent.Right = y;
    y.Left <- node;
    node.Parent <- y

Я получил предложение для реализации его прямой, но не используя 'касательно' ключевого слова, которое я попробовал сначала. Это - то, как я сделал это:

public static void LeftRotate(sRbTreeNode root, sRbTreeNode node)
    {
        sRbTreeNode y = node.Right;
        node.Right = y.Left;
        if (y.Left != null)
            y.Left.Parent = node;
        y.Parent = node.Parent;
        if (node.Parent == null)
            root = y;
        else
            if (node == node.Parent.Left)
                node.Parent.Left = y;
            else
                node.Parent.Right = y;
        y.Left = node;
        node.Parent = y;
    }

Теперь, когда я отлаживаю, я вижу, что это хорошо работает, но объекты, которые я передаю этому методу, только повернуты в рамках метода. Когда это оставляет этот метод, кажется, что не было никакого изменения в фактических узлах. Именно поэтому я думал об использовании 'касательно' ключевых слов во-первых.

Что я делаю неправильно?

5
задан Bill the Lizard 23 September 2012 в 01:59
поделиться

3 ответа

Потому что в теле вашего метода вы делаете следующее:

root = y;

вам нужно передать root с модификатором ref. node он не нужен, потому что node сам никогда не обновляется, чтобы указывать на другое ndoe. .

2
ответ дан 15 December 2019 в 01:00
поделиться

Я не вижу причин, почему у вас должны были возникнуть проблемы со ссылками - узлы Left/Right/Parent могут быть скопированы, как в этом псевдокоде.

Вы должны быть в состоянии расширить его до C# без особых проблем - если только вы не используете ключевое слово 'ref', в этом случае вы вполне можете получить непредсказуемые результаты.

Возможно, если вы покажете код, который вы на самом деле написали, мы сможем помочь отладить его.

1
ответ дан 15 December 2019 в 01:00
поделиться

Мои рекомендации:

  • Не включайте родительские указатели. Они не являются необходимыми для алгоритмов вставки или удаления и сделают ваш код более сложным. Например, LeftRotate может быть написан с одним параметром и будет примерно вдвое длиннее, если не использовать родительские указатели.
  • Используйте enum для свойства Color, а не string, и инициализируйте его в конструкторе.
  • Прочитайте эту статью, если вы еще этого не сделали.
1
ответ дан 15 December 2019 в 01:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: