Exemplo n.º 1
0
 private void DeleteKey(int key, Node <T> node, ref bool needToMerge, ref Keys <T> returns)
 {
     // Если находимся в листе, удаляем ключ, если элемент остался пуст, передаём наверх, что нужно объединение.
     if (node.IsLeaf)
     {
         if (node.Keys.Where(a => a.Key == key).Count() != 0)
         {
             if (node.Keys.Count == 1)
             {
                 needToMerge = true;
                 node.Keys.Clear();
             }
             else
             {
                 needToMerge = false;
                 node.Keys.Remove(node.Keys.Find(a => a.Key == key));
                 returns.Copy(node.Keys[0]);
             }
         }
     }
     // Если находимся в узле, ищем, в какой из потомков идти.
     else
     {
         int i = 0;
         while (i < node.Keys.Count)
         {
             int k = node.Keys[i].Key;
             if (key < k)
             {
                 DeleteKey(key, node.Next[i], ref needToMerge, ref returns);
                 break;
             }
             else if ((key == k) || (i == node.Keys.Count - 1))
             {
                 if (i < node.Next.Count() - 1)
                 {
                     i++;
                 }
                 DeleteKey(key, node.Next[i], ref needToMerge, ref returns);
                 break;
             }
             else
             {
                 i++;
             }
         }
         // Если необходимо объединение, значит уровнем ниже есть пустой узел/лист.
         if (needToMerge)
         {
             // Если число потомков больше одного, удаляем пустой, иначе передаём наверх о необходимости объединения.
             if (node.Next.Count > 1)
             {
                 // Если в поиске остановились на последнем, удаляем последний.
                 if (i == node.Keys.Count)
                 {
                     node.Keys.RemoveAt(i - 1);
                     node.Next.RemoveAt(i);
                 }
                 // Если на первом, удаляем первый.
                 else if (i == 0)
                 {
                     node.Keys.RemoveAt(0);
                     node.Next.RemoveAt(0);
                 }
                 // Если в середине, то проверяем наличие в узле искокого ключа.
                 else
                 {
                     // Если он есть, удаляем.
                     if (node.Keys.Find(a => a.Key == key) != null)
                     {
                         node.Keys.Remove(node.Keys.Find(a => a.Key == key));
                     }
                     // Иначе удаляем ключ, ведущий на пустого потомка.
                     else
                     {
                         node.Keys.RemoveAt(i - 1);
                     }
                     // Удаляем пустого потомка.
                     node.Next.RemoveAt(i);
                 }
                 // Если вдруг ключей не осталось, берём первый ключ у первого потомка.
                 if (node.Keys.Count == 0)
                 {
                     node.Keys.Add(node.Next[0].Keys[0]);
                 }
                 // Выключаем флаг.
                 needToMerge = false;
             }
         }
         // Если объединение не требуется, при наличии искомого ключа в узле, заменяем его на переданный снизу.
         else
         {
             if (node.Keys.Find(a => a.Key == key) != null)
             {
                 node.Keys[node.Keys.FindIndex(a => a.Key == key)] = returns;
             }
         }
     }
 }