Бинарное дерево поиска - проблема с удалением вершины
#39439192
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
Ссылка на профиль пользователя:
|
Участник
Откуда: Брянск
Сообщения: 269
|
|
Добрый вечер.
Занимаюсь написанием класса бинарного дерева, и вот возникла проблема: затруднения с написанием функции RemoveNode - случай, когда вершина имеет два потомка. В этом случае может быть несколько вариантов - у левой дочерней вершины нет правого потомка, есть правый потомок(спускаемся по правым потомкам до последнего, у него или нет потомков или есть).
Код
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207. 208. 209. 210. 211. 212. 213. 214. 215. 216. 217. 218. 219. 220. 221. 222. 223. 224. 225. 226. 227. 228. 229. 230. 231. 232. 233. 234. 235. 236. 237. 238. 239. 240. 241. 242. 243. 244. 245. 246. 247. 248. 249. 250. 251. 252. 253. 254. 255. 256. 257. 258. 259. 260. 261. 262. 263. 264. 265. 266. 267. 268. 269. 270. 271. 272. 273. 274. 275. 276. 277. 278. 279. 280. 281. 282. 283. 284. 285. 286. 287. 288. 289. 290. 291. 292. 293. 294. 295. 296. 297. 298. 299. 300. 301. 302. 303. 304. 305. 306. 307. 308. 309. 310. 311. 312. 313. 314. 315. 316. 317. 318. 319. 320. 321. 322. 323. 324. 325. 326. 327. 328. 329. 330. 331. 332. 333. 334. 335. 336. 337. 338. 339. 340. 341. 342. 343. 344. 345. 346. 347. 348. 349. 350.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace BinaryTree
{
public class BinaryNode
{
public BinaryNode Left { get; set; } // Левое поддерево
public BinaryNode Right { get; set; } // Правое поддеревго
public int value { get; set; } // Числовое значение вершины
public int level { get; set; } // Уровень дерева, на котором находится вершина
public BinaryNode(int value)
{
// Констркутор вершины
// На вход даём числовое значение вершины
this.value = value;
Left = null;
Right = null;
}
public int GetLevel()
{
return level;
}
}
public class BinaryTree
{
public BinaryNode node_root;
private int count;
private int min_value;
private int max_value;
public BinaryTree(BinaryNode root_node)
{
// Констркутор бинарного дерева
// На вход даём корневую вершину
this.node_root = root_node;
this.count = 1; // Поправка на корневую вершину
}
public int GetNodesCount()
{
return count;
}
public int GetMinValue()
{
return min_value;
}
public int GetMaxValue()
{
return max_value;
}
public void AddElement(int new_value)
{
if (new_value > max_value)
max_value = new_value;
else if (new_value < min_value)
min_value = new_value;
int level = 0;
if (node_root == null)
{
node_root = new BinaryNode(new_value);
node_root.level = level;
count++;
return;
}
else
InsertElement(node_root, new_value, level);
}
public void InsertElement(BinaryNode node, int new_value, int level)
{
level++;
if (new_value > node.value) // Новый элемент > элемент
{
// Проверяем правую ветвь
if (node.Right == null)
{
node.Right = new BinaryNode(new_value);
node.Right.level = level + 1;
count++;
}
else
InsertElement(node.Right, new_value, level);
}
else // Новый элемент < элемент
{
// Проверяем левую ветвь
if (node.Left == null)
{
node.Left = new BinaryNode(new_value);
node.Left.level = level + 1;
count++;
}
else
InsertElement(node.Left, new_value, level);
}
}
public bool FindValue(BinaryNode node, int search_value)
{
// На вход подаём корневую вершину
if (search_value == node.value)
return true;
else if (search_value < node.value)
{
if (node.Left == null)
return false;
else
return FindValue(node.Left, search_value);
}
else if (search_value > node.value)
{
if (node.Right == null)
return false;
else
return FindValue(node.Right, search_value);
}
return false;
}
public bool FindNode(BinaryNode node, int search_value, ref BinaryNode result_node)
{
// На вход подаём корневую вершину
if (search_value == node.value)
{
result_node = node;
return true;
}
else if (search_value < node.value)
{
if (node.Left == null)
return false;
else
return FindNode(node.Left, search_value, ref result_node);
}
else if (search_value > node.value)
{
if (node.Right == null)
return false;
else
return FindNode(node.Right, search_value, ref result_node);
}
return false;
}
public bool FindNodeParent(BinaryNode node, int search_value, ref BinaryNode result_node)
{
// На вход подаём корневую вершину
if (node.Left != null)
{
if (node.Left.value == search_value)
{
result_node = node;
return true;
}
if (FindNodeParent(node.Left, search_value, ref result_node))
return true;
}
if (node.Right != null)
{
if (node.Right.value == search_value)
{
result_node = node;
return true;
}
if (FindNodeParent(node.Right, search_value, ref result_node))
return true;
}
return false;
}
public void TraversePreorder(BinaryNode node) // Прямой обход дерева
{
// На вход подаём корневую вершину
// Здесь можем выполнять какие-нибудь действия
MessageBox.Show(Convert.ToString(node.value));
if (node.Left != null)
TraversePreorder(node.Left);
if (node.Right != null)
TraversePreorder(node.Right);
}
public void TraverseInorder(BinaryNode node) // Симметричный обход дерева
{
// На вход подаём корневую вершину
if (node.Left != null)
TraversePreorder(node.Left);
// Здесь можем выполнять какие-нибудь действия
MessageBox.Show(Convert.ToString(node.value));
if (node.Right != null)
TraversePreorder(node.Right);
}
public void TraversePostorder(BinaryNode node) // Обход дерева в обратном порядке
{
// На вход подаём корневую вершину
if (node.Left != null)
TraversePreorder(node.Left);
if (node.Right != null)
TraversePreorder(node.Right);
// Здесь можем выполнять какие-нибудь действия
MessageBox.Show(Convert.ToString(node.value));
}
public void TraverseDepth(BinaryNode node) // Обход дерева в ширину
{
// На вход подаём корневую вершину
Queue<BinaryNode> children = new Queue<BinaryNode>();
children.Enqueue(node); // Помещаем корень в очередь
while(children.Count != 0) // Пока очередь не пуста
{
BinaryNode nodeT = children.Dequeue(); // Берём следующую вершину из очереди
// Здесь можем выполнять какие-нибудь действия
MessageBox.Show(Convert.ToString(nodeT.value));
if (nodeT.Left != null)
children.Enqueue(nodeT.Left);
if (nodeT.Right != null)
children.Enqueue(nodeT.Right);
}
}
public bool RemoveNode(int value)
{
BinaryNode nodeT = new BinaryNode(6666);
if (!FindNode(node_root, value, ref nodeT)) // Не найдена вершина для удаления
return false;
else
{
if (nodeT.Left == null && nodeT.Right == null) // Терминальная вершина
{
BinaryNode nodeT2 = new BinaryNode(7777);
FindNodeParent(node_root, nodeT.value, ref nodeT2); // Ищем родительскую вершину для удаляемой вершины
if (nodeT2.Left == nodeT)
{
nodeT2.Left = null;
count--; // Уменьшаем счётчик количества вершин в дереве
return true;
}
else
{
nodeT2.Right = null;
count--; // Уменьшаем счётчик количества вершин в дереве
return true;
}
}
else if (nodeT.Left != null && nodeT.Right == null) // Имеет только левого потомка
{
BinaryNode nodeT3 = new BinaryNode(8888);
FindNodeParent(node_root, nodeT.value, ref nodeT3); // Ищем родительскую вершину для удаляемой вершины
nodeT3.Left = nodeT.Left;
count--; // Уменьшаем счётчик количества вершин в дереве
return true;
}
else if (nodeT.Left == null && nodeT.Right != null) // Имеет только правого потомка
{
BinaryNode nodeT4 = new BinaryNode(9000);
FindNodeParent(node_root, nodeT.value, ref nodeT4); // Ищем родительскую вершину для удаляемой вершины
nodeT4.Right = nodeT.Right;
count--; // Уменьшаем счётчик количества вершин в дереве
return true;
}
else if (nodeT.Left != null && nodeT.Right != null) // Имеет левого и правого потомка
{
BinaryNode nodeT5 = new BinaryNode(9001);
FindNodeParent(node_root, nodeT.value, ref nodeT5); // Ищем родительскую вершину для удаляемой вершины
if (nodeT.Left.Right == null) // Левый потомок не имеет правого потомка
{
BinaryNode nodeTT = new BinaryNode(9002);
nodeTT = nodeT.Right;
nodeT5.Left = nodeT.Left;
nodeT.Left.Right = nodeTT;
count--; // Уменьшаем счётчик количества вершин в дереве
return true;
}
else if (nodeT.Left.Right != null) //Левый потомок имеет правого потомка
{
BinaryNode nodeT6 = new BinaryNode(9003);
FindNodeParent(node_root, nodeT.value, ref nodeT6); // Ищем родительскую вершину для удаляемой вершины
if (nodeT.Left.Right.Right == null) // Правый потомок левого потомка не имеет правого потомка
{
if (nodeT6.Left == nodeT) // Удаляемая вершина является левым потомком родительской вершины
{
nodeT6.Left = nodeT.Left.Right.Right;
}
else
{
nodeT6.Right = nodeT.Left.Right.Right;
}
}
}
}
}
return false;
}
private void FindRightNode()
{
}
}
}
|
|