В-дерево на C#. Неправильный вывод в графвиз
Реализовал В-дерево на C#, но есть проблема: при добавлении нового значения в дерево в визуализации оно записывается третьим в узел. Уже много раз пересматривал код, но не могу найти, в чём ошибка. Прилагаю вывод из графвиза и выходной код программы формата .dot
using System;
using System.Collections.Generic;
using System.IO;
public class BTreeNode
{
public List<int> keys;
public List<BTreeNode> children;
public bool isLeaf;
public int n;
public BTreeNode(int n, bool isLeaf)
{
this.n = n;
this.isLeaf = isLeaf;
keys = new List<int>();
children = new List<BTreeNode>();
}
}
public class BTree
{
public BTreeNode root;
public int t;
public BTree(int t)
{
this.t = t;
root = new BTreeNode(t, true);
}
public void Insert(int key)
{
BTreeNode r = root;
if (r.keys.Count == 2 * t - 1)
{
BTreeNode s = new BTreeNode(t, false);
s.children.Add(r);
SplitChild(s, 0, r);
root = s;
InsertNonFull(s, key);
}
else
{
InsertNonFull(r, key);
}
}
private void InsertNonFull(BTreeNode x, int key)
{
int i = x.keys.Count - 1;
if (x.isLeaf)
{
x.keys.Add(0);
while (i >= 0 && key < x.keys[i])
{
x.keys[i + 1] = x.keys[i];
i--;
}
x.keys[i + 1] = key;
}
else
{
while (i >= 0 && key < x.keys[i])
{
i--;
}
i++;
if (x.children[i].keys.Count == 2 * t - 1)
{
SplitChild(x, i, x.children[i]);
if (key > x.keys[i])
{
i++;
}
}
InsertNonFull(x.children[i], key);
}
}
private void SplitChild(BTreeNode x, int i, BTreeNode y)
{
BTreeNode z = new BTreeNode(t, y.isLeaf);
x.children.Insert(i + 1, z);
x.keys.Insert(i, y.keys[t - 1]);
z.keys.AddRange(y.keys.GetRange(t, t - 1));
y.keys.RemoveRange(t - 1, t);
if (!y.isLeaf)
{
z.children.AddRange(y.children.GetRange(t, t));
y.children.RemoveRange(t, t);
}
}
public void PrintDotFile(string filePath)
{
using (StreamWriter sw = new StreamWriter(filePath))
{
sw.WriteLine("digraph BTree {");
PrintDotNode(root, sw);
sw.WriteLine("}");
}
}
private void PrintDotNode(BTreeNode node, StreamWriter sw)
{
string label = string.Join(",", node.keys);
sw.WriteLine($"node{node.GetHashCode()} [shape=box, label=\"{label}\"];");
if (!node.isLeaf)
{
for (int i = 0; i < node.children.Count; i++)
{
sw.WriteLine($"node{node.GetHashCode()} -> node{node.children[i].GetHashCode()};");
PrintDotNode(node.children[i], sw);
}
}
}
}
public class Program
{
public static void Main()
{
BTree bTree = new BTree(2); // Создаем B-дерево с t=2
bTree.Insert(1);
bTree.Insert(2);
bTree.Insert(3);
bTree.Insert(4);
bTree.Insert(5);
bTree.Insert(6);
bTree.Insert(7);
bTree.Insert(8);
bTree.Insert(9);
bTree.Insert(10);
bTree.Insert(11);
bTree.PrintDotFile("btree.dot"); // Выводим результат в файл btree.dot
}
}