Advertisement
paranid5

BTree (Rust)

Jul 22nd, 2020
813
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.03 KB | None | 0 0
  1. /**
  2.  *   _____________________________________
  3.  *  |                                    |
  4.  * | О СТРУКТУРЕ И КАК ЕЙ ПОЛЬЗОВАТЬСЯ  |
  5.  *|____________________________________|
  6.  *
  7.  *-------------------------О СТРУКТУРЕ----------------------------------------------------------------
  8.  *
  9.  * Бинарное дерево - это структура данных,
  10.  * которая имеет корень, значение и две ветви - правую и левую,
  11.  * которые, в свою очередь, также хранят значения и две ветви.
  12.  * Ветви могут быть как пустыми, так и непустыми.
  13.  * Так же ветвь хранит ссылку на отцовскую ветвь,
  14.  * если та не является родителем (т.е. инициализированна через Empty)
  15.  * Значение представленно дженериком T (аналог шаблона С++)
  16.  *
  17.  * --------------ПРАВИЛА ХРАНЕНИЯ И ИСПОЛЬЗОВАНИЯ-------------------------------------------------
  18.  *
  19.  * В БИНАРНОМ ДЕРЕВЕ КЛЮЧИ ПРАВОГО ПОДДЕРЕВА БОЛЬШЕ КЛЮЧЕЙ ЛЕВОГО ПОДДЕРЕВА
  20.  * Это освновополагающее правило размещения в дереве. Рассмотрим его подробнее:
  21.  * Допустим, у нас есть ключ с неким значением и дерево (непустое)
  22.  * Мы будем идти вглубь дерева, и на каждом вхождении проверять ключи ветвей
  23.  * Если ключ меньше ключа ветви, то отправляемся в правую ветвь,
  24.  * иначе идём в левую ветвь. Так идём, пока не дойдём то конца всей корневой системы
  25.  * Когда дошли, то проверяем наш ключ и ключ ветви, выбираем нужную ветвь
  26.  * и определяем родителя для новой ветви по указателю, тем самым мы можем ходить по дереву
  27.  */
  28.  
  29. //---------------------------------------------------------------------------------------------------------
  30.  
  31. /*
  32. * Будем хранить всё в enum (перечисление)
  33. * В случае, когда ветвь пуста, то мы определяем её как Empty,
  34. * иначе определяем её как NonEmpty. Перечисления в Rust позволяют
  35. * хранить данные для параметров перечислений. Здесь мы храним всё
  36. * как Box<TreeNode<T>>. Box - указатель на кучу, который
  37. * задаёт размер структуре.
  38. *
  39. * TreeNode<T> - универсальная структура, которая основана на типе T.
  40. * Тип T - дженерик (или шаблон С++), для использования которого Rust
  41. * требует определения трейтов (если говорить коротко - аналогов
  42. * интерфейсов). Для типа T мы определили трейты PartialEq (сравнение
  43. * на равенство или неравенство), PartialOrd (сравнения >, <, <=, >=),
  44. * Clone и Copy (для копирования. Кстати, трейты также, как и интерфейсы
  45. * умеют "наследовать" друг друга. Так, например, Clone - дочерний трейт
  46. * для Copy. Т.к. Clone наследует Copy, то реализуя трейт Clone, мы обязаны
  47. * реализовывать Copy)
  48. */
  49.  
  50. pub enum BTree<T>
  51. // Храним всё дерево как перечисление
  52. where
  53.     T: PartialOrd + PartialEq + Clone + Copy, // определяем трейты для дженерика T
  54. {
  55.     Empty,                      // Пусто
  56.     NonEmpty(Box<TreeNode<T>>), // Не пусто
  57. }
  58.  
  59. pub struct TreeNode<T>
  60. // Структура ветвь, с помощью которой
  61. where
  62.     // мы можем передвигаться по дереву
  63.     T: PartialOrd + PartialEq + Clone + Copy, // Для T используем те же трейты
  64. {
  65.     key: T,           // Значение, которое мы храним на ветви
  66.     right: BTree<T>,  // Правая ветвь
  67.     left: BTree<T>,   // Левая ветвь
  68.     parent: BTree<T>, // Родительская ветвь
  69. }
  70.  
  71. //-------------------------------------------------------------------------------------------------------
  72.  
  73. impl<T> BTree<T>
  74. // Реализация всех методов для дерева
  75. where
  76.     BTree<T>: PartialOrd + PartialEq + Clone + Copy, // Дерево также обязано иметь свои трейты,
  77.     T: PartialOrd + PartialEq + Clone + Copy,        // при том те же, что и T
  78. {
  79.     /*
  80.      * Метод new() - конструктор, который создаёт новый
  81.      * экземпляр дерева. По умолчанию наше дерево пустое,
  82.      * чтобы пользователю было удобно им пользоваться,
  83.      * а не утруждать себя добавлениями-удалениями
  84.      */
  85.  
  86.     pub fn new() -> Self {
  87.         BTree::Empty
  88.     }
  89.  
  90.     //----------------------------------------------------------------------------------------------------------
  91.  
  92.     /*
  93.      * Методы ignore() и ignore_mut() конвертирует BTree<T> в &Box<TreeNode<T>>.
  94.      * Т.к. наше дерево может быть пусто, то вызываем панику,
  95.      * иначе всё корректно и возвращаем ссылку
  96.      */
  97.  
  98.     fn ignore(&self) -> &Box<TreeNode<T>> {
  99.         if let BTree::NonEmpty(ref node) = *self {
  100.             return node;
  101.         } else {
  102.             panic!("Empty tree");
  103.         }
  104.     }
  105.  
  106.     fn ignore_mut(&mut self) -> &mut Box<TreeNode<T>> {
  107.         if let BTree::NonEmpty(ref mut node) = *self {
  108.             return node;
  109.         } else {
  110.             panic!("Empty tree");
  111.         }
  112.     }
  113.  
  114.     //----------------------------------------------------------------------------------------------------------
  115.  
  116.     /*
  117.      * Метод insert() добавляет в дерево новую ветвь,
  118.      * значение которой устанавливает пользователь
  119.      * Моя реализация дерева поддерживает хранение ветвей,
  120.      * которые имеют одинаковые значения.
  121.      */
  122.  
  123.     pub fn insert(&mut self, val: &T) {
  124.         let mut new_node = TreeNode {
  125.             key: (*val).clone(),
  126.             right: BTree::Empty,
  127.             left: BTree::Empty,
  128.             parent: BTree::Empty,
  129.         };
  130.  
  131.         let mut root2 = *self;
  132.         let mut root3 = BTree::Empty;
  133.  
  134.         while root2 != BTree::Empty {
  135.             root3 = root2;
  136.             if val < &root2.ignore().key {
  137.                 root2 = root2.ignore().left;
  138.             } else {
  139.                 root2 = root2.ignore().right;
  140.             }
  141.         }
  142.  
  143.         new_node.parent = root3;
  144.  
  145.         if val < &root3.ignore().key {
  146.             root3.ignore_mut().left = BTree::NonEmpty(Box::new(new_node));
  147.         } else {
  148.             root3.ignore_mut().right = BTree::NonEmpty(Box::new(new_node));
  149.         }
  150.     }
  151.  
  152.     //----------------------------------------------------------------------------------------------------------
  153.  
  154.     /*
  155.      * Метод find() ищет ветвь,
  156.      * значение которой равно заданному пользователю.
  157.      * Т.к. дерево может хранить ветви с повторяющимися значениями
  158.      * то мы находим ту ветвь, которая находится ближе всего
  159.      * к макушке (началу) дерева.
  160.      *
  161.      * Входной параметр - искомое значение.
  162.      * В случае успеха мы возвращаем непустую ветвь (BTree<T>),
  163.      * Иначе мы возвращаем совершенно пустую ветвь (Empty).
  164.      */
  165.  
  166.     pub fn find(&self, val: &T) -> BTree<T> {
  167.         let mut root2 = *self;
  168.  
  169.         while root2 != BTree::Empty {
  170.             if val < &root2.ignore().key {
  171.                 root2 = root2.ignore().left
  172.             } else if val < &root2.ignore().key {
  173.                 root2 = root2.ignore().right;
  174.             } else {
  175.                 return root2;
  176.             }
  177.         }
  178.  
  179.         BTree::Empty
  180.     }
  181.  
  182.     //----------------------------------------------------------------------------------------------------------
  183.  
  184.     /*
  185.      * Методы min_key() и max_key() ищет минимальную/максимальную ветвь поддерева.
  186.      * Т.к. дерево может хранить ветви с одинаковыми значениями,
  187.      * то мы вернём последнее наименьшее/наибольшее вхождение.
  188.      *
  189.      * Т.к. дерево может быть пустым, то мы вернём пустое дерево (Empty).
  190.      * Иначе мы найдём хоть что-то, и ветвь с этим мы и вернём
  191.      */
  192.  
  193.     pub fn min_key(&self) -> BTree<T> {
  194.         let mut min = *self;
  195.  
  196.         while min.ignore().left != BTree::Empty {
  197.             min = min.ignore().left;
  198.         }
  199.  
  200.         min
  201.     }
  202.  
  203.     pub fn max_key(&self) -> BTree<T> {
  204.         let mut max = *self;
  205.  
  206.         while max.ignore().right != BTree::Empty {
  207.             max = max.ignore().right;
  208.         }
  209.  
  210.         max
  211.     }
  212.  
  213.     //----------------------------------------------------------------------------------------------------------
  214.  
  215.     /*
  216.      * Метод next() находит ветвь, значение которой является следующим
  217.      * для текущего т.е. минимальным, но большим или равным текущему.
  218.      *
  219.      * Т.к. всё, что больше, хранится в дереве справа, то если наше дерево
  220.      * имеет правую ветвь, то мы пользуемся методом min_key() и находим
  221.      * такую ветвь, что её значение будет минимальным.
  222.      * Если же дерево не имеет правую ветвь, то мы идём вверх по дереву
  223.      * и ищем такую родительскую ветвь, у которой есть правая, а дальше
  224.      * используем min_key() и находим нужную ветвь.
  225.      *
  226.      * Т.к. дерево может быть пустым, то мы возвращаем пустое дерево,
  227.      * иначе возвращаем непустое дерево с нужным значением.
  228.      */
  229.  
  230.     pub fn next(&self) -> BTree<T> {
  231.         let node = *self;
  232.         return if node.ignore().right != BTree::Empty {
  233.             node.ignore().right.min_key()
  234.         } else {
  235.             let mut l = node.ignore().parent;
  236.             let mut p = *self;
  237.             let mut check = node.ignore().parent;
  238.  
  239.             if let BTree::NonEmpty(ref mut node_l) = check {
  240.                 while l != BTree::Empty && p == node_l.right {
  241.                     p = l;
  242.                     l = node_l.parent;
  243.                 }
  244.             }
  245.             l
  246.         };
  247.     }
  248.  
  249.     //----------------------------------------------------------------------------------------------------------
  250.  
  251.     /*
  252.      * Метод remove() очищает ветвь по значению.
  253.      * Возможны 3 случая размещения удаляемой ветки:
  254.      *
  255.      * 1) Когда у ветви нет дочерних ветвей.
  256.      * В этом случае мы просто удаляем ветвь,
  257.      * предварительно обнулив её для родителей
  258.      *
  259.      * 2) Когда у ветви есть 1 дочерняя ветвь.
  260.      * В этом случае просто удаляем узел,
  261.      *  и на его место ставим дочернюю ветвь
  262.      *
  263.      * 3) Когда у ветви есть обе дочерние ветви.
  264.      * В этом случае ищем такую ветвь,
  265.      * что она будет следующей для текущей.
  266.      * Ставим этот узел на место удаляемой.
  267.      *
  268.      * Возвращаем удалённую ветвь, возможно
  269.      * она ещё пригодится пользователю.
  270.      * Если же дерево было пусто, то
  271.      * возвращаем пустое дерево.
  272.      */
  273.  
  274.     pub fn remove(&mut self, val: &T) -> BTree<T> {
  275.         let p = *self;
  276.         let mut l = BTree::Empty;
  277.  
  278.         l = p.find(val);
  279.  
  280.         if l == BTree::Empty {
  281.             return BTree::Empty;
  282.         }
  283.  
  284.         if l.ignore().left == BTree::Empty && l.ignore().right == BTree::Empty {
  285.             let mut m = l.ignore().parent;
  286.             if l == m.ignore().right {
  287.                 m.ignore_mut().right = BTree::Empty;
  288.             } else {
  289.                 m.ignore_mut().left = BTree::Empty;
  290.             }
  291.             drop(l);
  292.         }
  293.  
  294.         if l.ignore().left == BTree::Empty && l.ignore().right != BTree::Empty {
  295.             let mut m = l.ignore().parent;
  296.             if l == m.ignore().right {
  297.                 m.ignore_mut().right = l.ignore().left;
  298.             } else {
  299.                 m.ignore_mut().left = l.ignore().left;
  300.             }
  301.             drop(l);
  302.         }
  303.  
  304.         if l.ignore().left != BTree::Empty && l.ignore().right != BTree::Empty {
  305.             let mut m = l.next();
  306.             l.ignore_mut().key = m.ignore().key;
  307.             if m.ignore().right == BTree::Empty {
  308.                 if m.ignore().parent.ignore().right == BTree::Empty {
  309.                     m.ignore_mut().parent.ignore_mut().left = BTree::Empty;
  310.                 } else {
  311.                     m.ignore_mut().parent.ignore_mut().left = m.ignore().right;
  312.                 }
  313.             }
  314.  
  315.             drop(m);
  316.         }
  317.         *self
  318.     }
  319.     //----------------------------------------------------------------------------------------------------------
  320.  
  321.     /*
  322.      * Методы get_key() и get_key_mut() возвращают значение ветви
  323.      * Т.к. дерево может быть пустым,
  324.      * то методы ignore() и ignore_mut() будут вызывать панику
  325.      */
  326.  
  327.     pub fn get_key(&self) -> &T {
  328.         &(*self).ignore().key
  329.     }
  330.  
  331.     pub fn get_key_mut(&mut self) -> &mut T {
  332.         &mut (*self).ignore_mut().key
  333.     }
  334.  
  335.     //----------------------------------------------------------------------------------------------------------
  336.  
  337.     /*
  338.      * Метод first() макушку дерева.
  339.      * Метод призван помочь пользователю передвигаться по дереву
  340.      * В случае, когда дерево пусто, вызывается паника
  341.      */
  342.  
  343.     fn first(&self) -> Self {
  344.         let mut root = *self;
  345.         while root.ignore().parent != BTree::Empty {
  346.             root = root.ignore().parent;
  347.         }
  348.         root
  349.     }
  350.  
  351.     //-----------------------------------------------------------------------------------------------------------
  352.  
  353.     /*
  354.      * Методы begin() и end() позволяют пользователю
  355.      * передвигаться по дереву.
  356.      * Т.к. дерево может быть пустым,
  357.      * то будет вызвана паника
  358.      */
  359.  
  360.     pub fn begin(&self) -> Self {
  361.         let mut root = (*self).first();
  362.         while root.ignore().left != BTree::Empty {
  363.             root = root.ignore().left;
  364.         }
  365.         root
  366.     }
  367.  
  368.     pub fn end(&self) -> Self {
  369.         let mut root = (*self).first();
  370.         while root.ignore().right != BTree::Empty {
  371.             root = root.ignore().right;
  372.         }
  373.         root
  374.     }
  375.  
  376.     //-----------------------------------------------------------------------------------------------------------
  377. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement