解决方案 »

  1.   

    给你写了一个demousing System;
    using System.Collections.Generic;
    using System.Linq;namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<Question> QuestionList = new List<Question>();            Question Q11 = new Question()
                {
                    Title = "1.1",
                    Score = 5,
                };            Question Q12 = new Question()
                {
                    Title = "1.2",
                    Score = 5,
                };            Question Q13 = new Question()
                {
                    Title = "1.3",
                    Score = 5,
                };            List<Question> Q13List = new List<Question>();            Question Q131 = new Question()
                {
                    Title = "1.3.1",
                    Score = 5,
                };            Question Q132 = new Question()
                {
                    Title = "1.3.2",
                    Score = 5,
                };            List<Question> Q132List = new List<Question>();            Question Q1321 = new Question()
                {
                    Title = "1.3.2.1",
                    Score = 5,
                };            Question Q1322 = new Question()
                {
                    Title = "1.3.2.2",
                    Score = 5,
                };            Question Q1323 = new Question()
                {
                    Title = "1.3.2.3",
                    Score = 5,
                };            Q132.Questions = Q132List;            Q13List.Add(Q131);
                Q13List.Add(Q132);            Q13.Questions = Q13List;            List<Question> Q1List = new List<Question>();
                Q1List.Add(Q11);
                Q1List.Add(Q12);
                Q1List.Add(Q13);            Question Q1 = new Question()
                {
                    Title = "First One",
                    Score = 25,
                    Questions = Q1List,
                };            Question Q2 = new Question()
                {
                    Title = "Second",
                    Score = 25,
                };            Question Q3 = new Question()
                {
                    Title = "Third",
                    Score = 25,
                };            QuestionList.Add(Q1);
                QuestionList.Add(Q2);
                QuestionList.Add(Q3);            var all = GetAll(QuestionList);
                Console.WriteLine("现在总共有 {0} 个Question。", all.Count());            var search = (from t in all
                              let q = t.Item1
                              where q.Title == "1.3.2" && q.Score == 5
                              select t).ToList();
                Console.WriteLine("找到{0}个符合条件的Question。", search.Count);            if (search.Any(r => r.Item1.Questions != null && r.Item1.Questions.Count > 0))
                    throw new Exception("Question的Questions集合不是空的,不能删除。");            foreach (var r in search)
                    r.Item2.Questions.Remove(r.Item1);      //从父Question的Questions属性中删除子Quenstion            Console.WriteLine("总共有 {0} 个Question。", GetAll(QuestionList).Count());
                Console.WriteLine("_________________按任意键结束。");
                Console.ReadKey();
            }        /// <summary>
            /// 返回所有的Question极其父Question。
            /// </summary>
            /// <param name="list">要遍历的树。</param>
            /// <returns>返回子Question及其父Question的 Tuple 结构列表。
            /// 对于顶级Question,则父Question为null。</returns>
            public static IEnumerable<Tuple<Question, Question>> GetAll(List<Question> list)
            {
                foreach (var r in GetAll(list, null))
                    yield return r;
            }        private static IEnumerable<Tuple<Question, Question>> GetAll(List<Question> list, Question parent)
            {
                foreach (var q in list)
                {
                    yield return new Tuple<Question, Question>(q, parent);
                    var children = q.Questions;
                    if (children != null && children.Count > 0)
                        foreach (var r in GetAll(q.Questions, q))
                            yield return r;
                }
            }    }    public class Question
        {
            public List<Question> Questions { get; set; }        public string Title { get; set; }        public int Score { get; set; }
        }
    }
    要删除它,必须先找到它。而要找到它,就需要递归搜索。在数据结构上,由于需要知道它的parent才能删除它,因此搜索的结果是得到 Tuple<Question,Question> 这样的“子-父”结构。在搜索功能上,使用了c#的迭代器功能,方便于将搜索应用到各种灵活的枚举功能的场合。例如使用 Linq 中。
      

  2.   

    这里边有两个功能点:首先是 GetAll 方法中,使用 5、6行代码对树进行深度优先搜索,并且以c#的迭代器模式输出出来。第二点就是在数据结构上返回了“子Question与其父Question的元组”。当然你也可以自定义一个有着两个属性的class。关键是要知道返回“两个”属性才够进行后续删除动作。
      

  3.   

    实际开发中,需要反之无限递归的情况出现。(你可以设计一个测试用例,仅仅有2个Questiion,就能产生一个无限递归)这个你自己修改吧。有多种形式。例如可以在递归查找(第二个Get方法)的参数上增加一个“已经查找出来的Question的收集集合,在 yield return 返回结果之前先判断一下是否重复。或者(更轻量的方式)是在这个方法参数上仅增加一个“递归深度”数值,并且程序判断最多仅递归5层。