-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path2_2_3.cpp
More file actions
134 lines (111 loc) · 3.99 KB
/
Copy path2_2_3.cpp
File metadata and controls
134 lines (111 loc) · 3.99 KB
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
/*//==============================================================================================================
Дано число N < 10^6 и последовательность целых чисел из [-2^31..2^31] длиной N.
Требуется построить бинарное дерево, заданное наивным порядком вставки.
Т.е., при добавлении очередного числа K в дерево с корнем root, если root→Key ≤ K, то узел K добавляется в правое
поддерево root; иначе в левое поддерево root.
Требования: Рекурсия запрещена. Решение должно поддерживать передачу функции сравнения снаружи.
Выведите элементы в порядке post-order (снизу вверх).
*/ //==============================================================================================================
#include <iostream>
#include <stack>
#include <functional>
using namespace std;
struct Node {
int key; // значение
Node* left; // левый ребенок
Node* right; // правый ребенок
explicit Node(int value);
~Node();
};
Node *insert(int N, Node *root);
void insertNode(Node*& root, int key, const function<bool(int, int)>& compare);
void postorderTraversal(Node* root);
void freeMemory(Node* root);
int main() {
int N; // число элементов в дереве
cin >> N;
Node* root = nullptr;
root = insert(N, root);
postorderTraversal(root);
freeMemory(root);
return 0;
}
Node *insert(int N, Node *root) {
function<bool(int, int)> compare = [](int a, int b) { // лямбда функция сравнения значений Node::key
return a <= b;
};
int key;
for (int i = 0; i < N; ++i) {
cin >> key;
insertNode(root, key, compare);
}
return root;
}
void insertNode(Node *&root, int key, const function<bool(int, int)>& compare) {
Node* newNode = new Node(key);
if (nullptr == root) {
root = newNode;
return;
}
Node* current = root;
for (;;) {
if (compare(current->key, key)) {
if (nullptr == current->right) {
current->right = newNode;
break;
}
current = current->right;
} else {
if (nullptr == current->left) {
current->left = newNode;
break;
}
current = current->left;
}
}
}
void postorderTraversal(Node *root) {
if (nullptr == root) {
return;
}
stack<Node*> st; // Стек для хранения вершин
Node* current = root;
Node* lastVisited = nullptr; // для избежания повторений
while (nullptr != current || !st.empty()) { // обход бинарного дерева снизу вверх (в порядке пост-последовательности)
if (nullptr != current) {
st.push(current);
current = current->left;
} else {
Node* top = st.top();
if (nullptr != top->right && lastVisited != top->right) {
current = top->right;
} else {
cout << top->key << " ";
lastVisited = top;
st.pop();
}
}
}
}
Node::Node(int value) : key(value), left(nullptr), right(nullptr) {}
Node::~Node() {
delete left;
delete right;
left = nullptr; // для безопасности
right = nullptr;
}
void freeMemory(Node* root) {
stack<Node*> st;
st.push(root);
for(int i = 0;!st.empty() && i < st.size()-1;++i) {
Node* current = st.top();
st.pop();
if (current->left) {
st.push(current->left);
}
if (current->right) {
st.push(current->right);
}
delete current;
}
}