示例#1
0
        /// <summary>
        /// Поиск элемента в дереве
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        /// В классе определен параметр finded для сокращения времени при удалении
        public bool Contains(T node)
        {
            if (Root == null)
            {
                return(false);
            }
            OneNode <T>          el    = Root;
            Queue <OneNode <T> > elems = new Queue <OneNode <T> >();

            elems.Enqueue(el);
            while (elems.Count > 0)
            {
                el = elems.Dequeue();
                if (el.info.CompareTo(node) == 0)
                {
                    finded = el;
                    return(true);
                }

                if (el.left != null)
                {
                    elems.Enqueue(el.left);
                }
                if (el.right != null)
                {
                    elems.Enqueue(el.right);
                }
            }
            finded = null;
            return(false);
        }
示例#2
0
        /// <summary>
        /// Удаление элемента из дерева, если дерево пусто  - исключение
        /// </summary>
        /// <param name="node"></param>
        public void Remove(T node)
        {
            if (IsEmpty)
            {
                throw new RemovingFromEmptyTree();
            }
            if (Contains(node))
            {
                if (OrderNodes.Count == 0)
                {
                    Clear();
                }
                else
                {
                    OneNode <T> inf = OrderNodes.Peek().right == null?OrderNodes.Peek().left : OrderNodes.Peek().right;

                    finded.info          = inf.info;
                    finded.nodeview.Text = finded.info.ToString();
                    OneNode <T> peeked = OrderNodes.Pop();
                    if (peeked.right == null)
                    {
                        peeked.left.nodeview.Remove();
                        peeked.left = null;
                    }
                    else
                    {
                        peeked.right.nodeview.Remove();
                        peeked.right = null;
                    }
                    --Count;
                }
            }
        }
示例#3
0
 /// <summary>
 /// Перебор и преобразование всех эл-тов дерева
 /// </summary>
 /// <param name="tree"></param>
 /// <param name="action"></param>
 public static void ForEach(ITree <T> tree, ActionDelegate <T> action)
 {
     //Если дерево неизменяемо - исключение
     if (tree is UnmutableTree <T> )
     {
         throw new AttemptOfChangingUnmutableTree();
     }
     //Специальная форма для кажого представления
     if (tree is ArrayTree <T> )
     {
         ArrayTree <T> t = (ArrayTree <T>)tree;
         for (int i = 0; i < tree.Count; ++i)
         {
             if (t[i] != null)
             {
                 t[i].info = action(t[i].info);
             }
         }
     }
     else
     {
         OneNode <T> one = ((ListTree <T>)tree).Root;
         ForEachList(one, action);
     }
 }
示例#4
0
 //Специальная функция, на случай, если дерево представлено цепочно
 private static void ForEachList(OneNode <T> node, ActionDelegate <T> action)
 {
     if (node != null)
     {
         node.info = action(node.info);
         ForEachList(node.left, action);
         ForEachList(node.right, action);
     }
 }
示例#5
0
 //Конструктор с 1 обязательным параметром - информационной частью
 public OneNode(T info, TreeNode v = null)
 {
     this.info = info;
     left      = right = null;
     if (v != null)
     {
         nodeview = v;
     }
     else
     {
         nodeview = new TreeNode();
     }
 }
示例#6
0
 //Конструктор без обязательных параметров
 public ListTree(TreeView tree = null)
 {
     Root       = null;
     finded     = null;
     Count      = 0;
     OrderNodes = new Stack <OneNode <T> >();
     if (tree != null)
     {
         view = tree;
     }
     else
     {
         view = new TreeView();
     }
 }
示例#7
0
        /// <summary>
        /// Реализация IEnumerable (обход дерева в ширину (Если дерево пусто - исключение))
        /// </summary>
        /// <returns></returns>
        public IEnumerator <T> GetEnumerator()
        {
            if (IsEmpty)
            {
                throw new TryToGetEmptyTree();
            }
            Queue <OneNode <T> > nodesTree = new Queue <OneNode <T> >();

            nodesTree.Enqueue(Root);
            while (nodesTree.Count > 0)
            {
                OneNode <T> b = nodesTree.Dequeue();
                yield return(b.info);

                if (b.left != null)
                {
                    nodesTree.Enqueue(b.left);
                }
                if (b.right != null)
                {
                    nodesTree.Enqueue(b.right);
                }
            }
        }
示例#8
0
 /// <summary>
 /// Добавление нового уникального элемента в дерево
 /// </summary>
 /// <param name="node"></param>
 public void Add(T node)
 {
     //если дерево пусто - просто добавляем в корень
     if (Root == null)
     {
         TreeNode rootNode = new TreeNode(node.ToString());
         view.Nodes.Add(rootNode);
         Root = new OneNode <T>(node, rootNode);
     }
     else
     {
         if (!Contains(node))
         {
             //Очередь из узлов по уровням
             Queue <OneNode <T> > nodes = new Queue <OneNode <T> >();
             //Буфер для чтения след узла
             OneNode <T> buf;
             //Буфер для хранения узла с пустым правым поддеревом
             OneNode <T> bufForRight = null;
             nodes.Enqueue(Root);
             while (nodes.Count > 0)
             {
                 //Определяем кол-во узлов на уровне
                 int c = nodes.Count;
                 //Проход по уровню
                 for (int i = 0; i < c; ++i)
                 {
                     buf = nodes.Dequeue();
                     //если у узла левое поддерево пусто, то добавляем его и возвращаем из функции
                     if (buf.left == null)
                     {
                         TreeNode NewNode = buf.nodeview.Nodes.Add(node.ToString());
                         buf.left = new OneNode <T>(node, NewNode);
                         OrderNodes.Push(buf);
                         ++Count;
                         return;
                     }
                     else
                     {
                         //Если нет, то кладем в очередь и анализируем правое поддерево
                         nodes.Enqueue(buf.left);
                         //Если таких узлов еще не встречалось, а это первый - запоминаем его
                         if (buf.right == null && bufForRight == null)
                         {
                             bufForRight = buf;
                         }
                     }
                     //Иначе -также кладем в очередь
                     if (buf.right != null)
                     {
                         nodes.Enqueue(buf.right);
                     }
                 }
                 //Ессли нашли узел с пустым правым поддеревом - то создаем в правом поддереве новый узел и возвращаем его
                 if (bufForRight != null)
                 {
                     TreeNode NewNode1 = bufForRight.nodeview.Nodes.Add(node.ToString());
                     bufForRight.right = new OneNode <T>(node, NewNode1);
                     OrderNodes.Push(bufForRight);
                     ++Count;
                     return;
                 }
             }
         }
     }
 }