CPPX 2.1.0
A Modern C++ Utility Library
Loading...
Searching...
No Matches
avl.tpp
Go to the documentation of this file.
1#pragma once
2#include "../include/cppx.h"
3
4namespace stl_ext
5{
6
7template <typename T> int AVLTree<T>::get_height(const Node<T> *node) const
8{
9 return node ? node->m_height : 0;
10}
11
12template <typename T> int AVLTree<T>::get_balance_factor(const Node<T> *node) const
13{
14 return node ? get_height(node->p_left) - get_height(node->p_right) : 0;
15}
16
17template <typename T> void AVLTree<T>::update_height(Node<T> *node)
18{
19 if (!node)
20 return;
21 int left_h = get_height(node->p_left);
22 int right_h = get_height(node->p_right);
23 node->m_height = static_cast<std::int8_t>(1 + std::max(left_h, right_h));
24}
25
26template <typename T> Node<T> *AVLTree<T>::rotate_left(Node<T> *x)
27{
28 Node<T> *y = x->p_right;
29 x->p_right = y->p_left;
30 y->p_left = x;
31 update_height(x);
32 update_height(y);
33 return y;
34}
35
36template <typename T> Node<T> *AVLTree<T>::rotate_right(Node<T> *x)
37{
38 Node<T> *y = x->p_left;
39 x->p_left = y->p_right;
40 y->p_right = x;
41 update_height(x);
42 update_height(y);
43 return y;
44}
45
46template <typename T> Node<T> *AVLTree<T>::rebalance(Node<T> *node)
47{
48 update_height(node);
49 int balance = get_balance_factor(node);
50
51 if (balance > 1)
52 {
53 if (get_balance_factor(node->p_left) < 0)
54 node->p_left = rotate_left(node->p_left);
55 return rotate_right(node);
56 }
57
58 if (balance < -1)
59 {
60 if (get_balance_factor(node->p_right) > 0)
61 node->p_right = rotate_right(node->p_right);
62 return rotate_left(node);
63 }
64
65 return node;
66}
67
68template <typename T> void AVLTree<T>::insert(const T &val)
69{
70 if (!this->p_head)
71 {
72 this->p_head = this->make_node(val);
73 return;
74 }
75
76 std::vector<Node<T> **> path;
77 Node<T> **link = &this->p_head;
78
79 while (*link)
80 {
81 path.push_back(link);
82 if (val < (*link)->m_data)
83 link = &(*link)->p_left;
84 else if (val > (*link)->m_data)
85 link = &(*link)->p_right;
86 else
87 return;
88 }
89
90 *link = this->make_node(val);
91
92 for (auto it = path.rbegin(); it != path.rend(); ++it)
93 {
94 *(*it) = rebalance(*(*it));
95 }
96}
97
98template <typename T> void AVLTree<T>::remove(const T &val)
99{
100 struct Frame
101 {
102 Node<T> **link;
103 };
104
105 std::vector<Node<T> **> path;
106 Node<T> **link = &this->p_head;
107
108 while (*link)
109 {
110 if (val < (*link)->m_data)
111 {
112 path.push_back(link);
113 link = &(*link)->p_left;
114 }
115 else if (val > (*link)->m_data)
116 {
117 path.push_back(link);
118 link = &(*link)->p_right;
119 }
120 else
121 {
122 Node<T> *node = *link;
123 if (!node->p_left)
124 {
125 *link = node->p_right;
126 this->m_pool.deallocate(node);
127 }
128 else if (!node->p_right)
129 {
130 *link = node->p_left;
131 this->m_pool.deallocate(node);
132 }
133 else
134 {
135 Node<T> **succ_link = &node->p_right;
136 std::vector<Node<T> **> succ_path;
137 while ((*succ_link)->p_left)
138 {
139 succ_path.push_back(succ_link);
140 succ_link = &(*succ_link)->p_left;
141 }
142
144 node->m_data = succ->m_data;
145 *succ_link = succ->p_right;
146 this->m_pool.deallocate(succ);
147
148 for (auto it = succ_path.rbegin(); it != succ_path.rend(); ++it)
149 {
150 *(*it) = rebalance(*(*it));
151 }
152 *link = rebalance(node);
153 }
154
155 for (auto it = path.rbegin(); it != path.rend(); ++it)
156 {
157 *(*it) = rebalance(*(*it));
158 }
159 return;
160 }
161 }
162}
163
164} // namespace stl_ext
void remove(const T &val) override
Definition avl.tpp:98
void insert(const T &val) override
Definition avl.tpp:68
Definition cppx.h:17