已知parentId 与 ID,求删除该parentId下的所有id,注意:parentId下有很多Id,Id下又有N多id。这个用递归可以实现,我知道思路但写不出来。谢谢!

解决方案 »

  1.   


    传入parentId与id参数,根据传入的参数去select该节点的id(select id from T where parentId=id),发现该id无子节点的时候,就删除该节点(id)。
      

  2.   

    “发现该id无子节点的时候,就删除该节点(id)”,你这个说法与题目不符。题目是删除所有id,就算是有子节点,也要删除。而你给偷换了需求。写一个程序,首先一点是要写出方法名字、参数名字和数据类型、返回的数据类型。写出这些就够了,至于内部如何实现,还并不重要。我知道有些人比较懒惰,不愿意对这个“形式设计”花功夫,只喜欢学点编程语句。这就是你思路混乱的原因。其实思路就好像是数学符号函数、和数学归纳法,是很简单的东西,关键是要会那种形式表达!这类逻辑很简单,不管能不能实现,你应该先写成一个形式上对于“输入和输出”类型比较明确的为代码。例如void 删除子节点(node x)
    {
         foreach(var child in GetChildren(x))
         {
            删除子节点(child);
            x.Nodes.Remove(child);
         }
    }
      

  3.   

    嗯,谢谢!我想,我还没表达清楚。“发现该id无子节点的时候,就删除该节点(id)”这句话应该是“直到发现该id无子节点的时候,就删除该节点(id)”,因为一发现节点就删除,那么后面的节点就找不到了。所以只有在遍历的时候,发现当前的节点无子节点了,才去删除。这里“节点”是我感觉使用节点更好表达。真正的结构是数据库的一张表,有一个parentId,一个id,然后对它们进行操作。并不是一个winfrom空间或者webfrom页面。谢谢!
      

  4.   

    比较含糊其辞的“设计”,其实往往是不愿意对输入输出类型做出简单地表达。它们只把眼睛盯在功能名词上,其实稍微懂得要对输入参数和输出进行描述,养成习惯,你就不再会这种“我知道思路可是写不出代码”的借口了。我不相信有“知道思路但是不会动手写代码”这种事情。(通常)一定是你自己比较懒惰。对于代码void 删除子节点(node x)
    {
         foreach(node child in GetChildren(x))
         {
            删除子节点(child);
            x.Nodes.Remove(child);
         }
    }仅仅写到这个程度就行了,这就是搞好了高层次的设计。然后,你需要花时间来论证一下,输入参数够了吗?为什么不需要更多的参数了?输出的是要求的结果吗?你这个时候不应该花精力去纠缠什么底层如何实现的问题,应该学会在这个层次先论证出结论,然后等有闲工夫时采取把这个方法中低层次的部分实现(但是这个方法的接口早已经定下来了,不会再改变了)。
      

  5.   

    先说重要的方面。你还是没有理解我的意思。就算是你把伪代码写改成void 删除子节点(node x)
    {
         foreach(node child in GetChildren(x))
         {
            if( !存在子节点(child))
               x.Nodes.Remove(child);
         }
    }
    这跟你要处理的东西是数据库表记录、内存里的对象、控件之类的,有关系吗?假设这里把node实际上只是一个简单的数据库表中的某个int类型的字段值,会影响这个程序的实现吗?你会因为什么“数据库表、内存对象、控件”的形式不同,而去推翻了这个程序吗?那么你需要有一种正规的程序设计课程,告诉你从哪一个出发点开始进行(伪)代码编写。
      

  6.   


    谢谢,我已经验证一下午了,就这个递归的,但总是出不来结果,我是根据一个id,然后sql里一个去查询出来的,代码里写不出。
      

  7.   

    如果LZ真的是思路清晰的话,那么应该不会存在你说代码写不出来的问题,就像你说的你删除id,还有很多子id那你遍历一边不是可以得到所以的子id了,这个同理可以得到你说的很多id再来写你会写不出来了?我不信!
      

  8.   

    到目前为止,已经解决了。alter procedure SP_Test
    @ClassID nchar(10)
    as
    declare @id int
    set @id=@ClassID;
     with RootNodeCTE(id,ParentID)
     as
     (
      Select PKID,ParentPKID from T
      where ParentPKID in (@id)
      Union all
      Select T.PKID,T.ParentPKID
      From RootNodeCTE
      inner join T on RootNodeCTE.id=T.ParentPKID
     )
     delete from T
     Where PKID In
     (
      Select id from RootNodeCTE
      union all
      Select @classid
     )
     
    以上是解决方法,当前选中行,在代码里delete。谢谢两位的热心解答。