将摩尔斯电码插入二叉树

时间:2014-05-06 02:06:18

标签: c++ binary-tree

我正在尝试将摩尔斯电码插入二叉树,但我的Insert()正在执行。我很难过为什么会失败。

二叉树类:

class BST
{
    private:
            struct Node
            {
                string letter;
                string code;
                Node *left;
                Node *right;
            };
            Node *root;

    public:
            BST()
            {
                root = NULL;
            }
            void Insert(Node *&r, string letter, string code)
            {
                if(r == NULL)
                {
                    r = new Node; 
                    r->letter = letter; 
                    r->code = code;
                    r->left = r->right = NULL; 
                }
            }
            void Insert(string letter, string code)
            {
                Node *r = root;
                if(r != NULL)
                {
                    for(int i = 0; i < code.length(); i++)
                    {
                        if(code[i] == '.') r = r->left;
                        else if(code[i] == '-') r = r->right;
                        else break;
                    }
                    Insert(r, letter, code);
                }
                else Insert(root, letter, code);
            }
};

主:

struct alphaTree
{
    string letter;
    string code;
};

alphaTree tree[] = {  
                       {"ROOT", ""},  {"E", "."},    {"T", "-"},    {"I", ".."},   {"A", ".-"},   {"N", "-."},   
                       {"M", "--"},   {"S", "..."},  {"U", "..-"},  {"R", ".-."},  {"W", ".--"},  {"D", "-.."},  
                       {"K", "-.-"},  {"G", "--."},  {"O", "---"},  {"H", "...."}, {"V", "...-"}, {"F", "..-."}, 
                       {"L", ".-.."}, {"P", ".--."}, {"J", ".---"}, {"B", "-..."}, {"X", "-..-"}, {"C", "-.-."}, 
                       {"Y", "-.--"}, {"Z", "--.."}, {"Q", "--.-"}  
                    };

for(int i = 0; i < 27; i++)
{
    t.Insert(tree[i].letter, tree[i].code);
}

我的tree[]数组的前3个元素已插入但尝试插入"I"时程序崩溃。

2 个答案:

答案 0 :(得分:1)

插入新节点时,父节点左右不会更新。

您可能认为父母已更新,因为您通过引用传递指针,但您传递的是r而不是r->leftr->root

一种可能的解决方案是使用**r代替*r中的void Insert(string letter, string code)

您可以更改以下内容:(Working example here

    void Insert(string letter, string code)
    {
        Node **r = &root;
        if(*r != NULL)
        {
            for(int i = 0; i < code.length(); i++)
            {
                assert(*r);
                if(code[i] == '.') r = &((*r)->left);
                else if(code[i] == '-') r = &((*r)->right);
                else break;
            }
            Insert(*r, letter, code);
        }
        else Insert(root, letter, code);
    }

与您的问题无关,但作为旁注:

  1. for(int i = 0; i < code.length(); i++)你正在比较一个 带有singed int的unsigned(length)。您应该将i更改为 的std :: string :: size_type的。
  2. 在功能void Insert(string letter, string code)中,您应该添加 在访问*r个孩子之前断言(* r)。

答案 1 :(得分:1)

你的问题在这里:

for(int i = 0; i < code.length(); i++)
{
    if(code[i] == '.') r = r->left;
    else if(code[i] == '-') r = r->right;
    else break;
}

此循环开始时,请确保r永远不会NULL。然而,由于树中只有一个元素,当您将其设置为NULLr = r->left时,它将立即变为r = r->right以进行下一次迭代,因为在该树中只有一个节点树及其leftright都是NULL

循环时,您不会检查r是否变为NULL

越早到达摩尔斯电码中包含两个或更多符号的元素,当r指针成为NULL时,您的应用程序就会尝试从for(int i = 0; i < code.length(); i++) { if (code[i] == '.') { if (r->left) r = r->left; else { // todo: code to bind a new node to r->left break; } } else // its always either '.' or '-' so there is no need to double check the symbol here { if (r->right) r = r->right; else { // todo: code to bind a new node to r->right break; } } } 读取。

您可能希望将代码扩展为更像这样的代码:

r

现在,您确保循环停止,而left仍然是有效指针。降序树中的最后一个有效指针。

当然,您仍然必须决定在此节点的right或{{1}}侧创建新节点。