我有一个树目录如下:目录
  目录一
    子目录一
    子目录二
  目录二
    子目录一
      子目录一
      子目录二
    子目录二
  目录三
  目录四
……这个树是根据数据库中生成的,采用递归方法加入到TreeView中,红色的部分也是采用递归方法浏览所有树节点,然后根据条件更改了节点的前景颜色,我现在想把变成红色的节点和其父节点保留,其余的删除,想用一个递归方法做,不知道有没有好的算法!!!!谢谢大家!

解决方案 »

  1.   

    我理解楼主说的是把红色的节点和其父结点(们)保留吧,如下,没测过,仅仅表示一下思路,有语法错误的话请见谅//返回的bool表示node节点能否被删除
    public bool DeleteNode(TreeNode node)
    {
        bool canBeDeleted = true;   //node节点能否被删除
        foreach(TreeNode childNode in node.ChildNodes)
        {
            if(DeleteNode(childNode))
                node.ChildNodes.remove(childNode);  //?不知道这样删除会不会对node.ChildNodes的遍历造成影响,如果有影响的话应该使用for循环倒序遍历
            else
                canBeDeleted = false;   //如果有子节点不能被删除,node也不能被删除
        }
        
        return canBeDeleted && node.ForeColor != Color.Red;   //如果所有子节点都被删除,并且node也不是红的,则node可以被删除
    }
      

  2.   

    public bool DeleteNode(TreeNode node) 
    {
        if (node.ForeColor == Color.Red)
            return false;
        if (node.ChildNodes.Count>0)
            foreach(TreeNode Node in node.ChildNodes)
                 if (DeleteNode(Node))
                    node.ChildNodes.remove(Node);  
        else
            return true;
      

  3.   

    public bool DeleteNode(TreeNode node) 
    {
        if (node.ForeColor == Color.Red)
            return false;
        if (node.ChildNodes.Count>0)
            foreach(TreeNode Node in node.ChildNodes)
                 if (DeleteNode(Node))
                    node.ChildNodes.remove(Node);  
        else
            return true;
      

  4.   

    不知道大家用的是哪个版本的...呵呵.我的NODE没有ChildNodes属性,只有Nodes属性,所以,我将其代码更改为:
    public bool DeleteNode(TreeNode node)
            {
                if (node.ForeColor == Color.Red)
                {
                    return false;
                }
                if (node.Nodes.Count > 0)
                {
                    foreach (TreeNode Node in node.Nodes)
                    {
                        if (DeleteNode(Node))
                        {
                            node.Nodes.Remove(Node);
                        }
                    }
                    return false;
                }
                else
                {
                    return true;
                }
            }程序运行就OK了.可是出现了问题......代码运行之后,该父NODE下如果有红色的子NODE,则正常,如果该 父NODE下没有红色的子NODE,而全部是黑色的,则该父NODE将把所有的子NODE删除后,该父NODE还存在,我的要求是不能存在空父NODE....不知道还有啥办法 !谢谢!!!
      

  5.   

    不知道大家用的是哪个版本的...呵呵.我的NODE没有ChildNodes属性,只有Nodes属性,所以,我将其代码更改为:
    public bool DeleteNode(TreeNode node)
            {
                if (node.ForeColor == Color.Red)
                {
                    return false;
                }
                if (node.Nodes.Count > 0)
                {
                    foreach (TreeNode Node in node.Nodes)
                    {
                        if (DeleteNode(Node))
                        {
                            node.Nodes.Remove(Node);
                        }
                    }
                    return false;
                }
                else
                {
                    return true;
                }
            }程序运行就OK了.可是出现了问题......代码运行之后,该父NODE下如果有红色的子NODE,则正常,如果该 父NODE下没有红色的子NODE,而全部是黑色的,则该父NODE将把所有的子NODE删除后,该父NODE还存在,我的要求是不能存在空父NODE....不知道还有啥办法 !谢谢!!!
      

  6.   

    public bool DeleteNode(TreeNode node)
            {
                if (node.ForeColor == Color.Red)
                {
                    return false;
                }
                if (node.Nodes.Count > 0)
                {
                    foreach (TreeNode Node in node.Nodes)
                    {
                        if (DeleteNode(Node))
                        {
                            node.Nodes.Remove(Node);
                        }
                    }
                    if (node.Nodes.Count == 0)
                    {
                        if (DeleteNode(node))
                        {
                            node.Remove();
                        }
                    }
                    return false;
                }
                else
                {
                    return true;
                }
            }
    我最后修改的代码.....好像测试没发现啥问题......就是不知道有没有漏洞啊!!!!!呵呵...谢谢大家.
      

  7.   

    额。因为是手写的,而且没测试,这样应该就对了,虽然我还是没测试,而且我加了注释public bool DeleteNode(TreeNode node)
    {
        if (node.ForeColor == Color.Red) 
            return false; // 往下走的路径中有一个节点是红色的,那父节点就不是可删的
        if (node.Nodes.Count > 0) // 当前节点是黑色的而且有子节点,那就依次判断子节点的路径
            foreach (TreeNode Node in node.Nodes)
                if (DeleteNode(Node)) // 递归调用,改子节点当其子子节点的父节点同理去判断
                    node.Nodes.Remove(Node); // 该子节点往下走的各种路径全都没发现过红色节点都走到了最后,那删除该子节点
                                                   // 而其子子节点们其实每次同理判断下已经被其父节点的逻辑判断下已删光了
        if (node.Nodes.Count == 0) // 如果是本来就没节点,说明这条路径已经走到最后了,还是没发现过红色节点,那就返回而且告诉父节点删了我吧
                                       // 如果是子节点们的路径都是黑色的,导致子节点们删光了,那也就返回而且告诉父节点删了我吧
            return true;
    }
      

  8.   

    真是谢谢Wartim啊...不过,代码还是有问题....在删除所有的空父节点后,因为你用的是foreach遍历集合,则集合中的值会更改,这样会导致异常即简单的解释就是:本来foreach遍历的集合中有5个对象,你遍历的时候,将集合中的某个对象删除了,这样,集合中的对象就少了一个,遍历就出错了.可能漏掉一个,也可能异常!!!所以,我后来发的那段代码也出现这个问题,你最后发的这个代码也出现了同样的问题....怎么样将代码改为不用foreach遍历集合,而且还可以顺序的遍历下去呢???
      

  9.   


    public bool DeleteNode(TreeNode node)
            {
                if (node.ForeColor == Color.Red)
                {
                    // 往下走的路径中有一个节点是红色的,那父节点就不是可删的
                    return false; 
                }
                // 当前节点是黑色的而且有子节点,那就依次判断子节点的路径
                if (node.Nodes.Count > 0)
                { 
                    //foreach (TreeNode Node in node.Nodes)
                    //{
                    //    // 递归调用,改子节点当其子子节点的父节点同理去判断
                    //    if (DeleteNode(Node))
                    //    {
                    //        // 该子节点往下走的各种路径全都没发现过红色节点都走到了最后,那删除该子节点
                    //        // 而其子子节点们其实每次同理判断下已经被其父节点的逻辑判断下已删光了
                    //        node.Nodes.Remove(Node); 
                    //    }
                    //}
                    for (int i = node.Nodes.Count - 1; i >= 0; i--)
                    {
                        if (DeleteNode(node.Nodes[i]))
                        {
                            node.Nodes.Remove(node.Nodes[i]);
                        }
                    }
                }
                // 如果是本来就没节点,说明这条路径已经走到最后了,还是没发现过红色节点,那就返回而且告诉父节点删了我吧
                // 如果是子节点们的路径都是黑色的,导致子节点们删光了,那也就返回而且告诉父节点删了我吧
                if (node.Nodes.Count == 0)
                { 
                    return true;
                }
                return false;
            }终于解决了谢谢Wartim,
    我将你的代码的foreach代码段换成了for循环。就可以了。。呵呵贴上完整代码,以便以后分享查阅。。如果没有更多的跟贴,明日散分结贴