-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathW11_P2.cpp
214 lines (197 loc) · 4.05 KB
/
W11_P2.cpp
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
//자료구조 11주차 실습 2번
//BST+sub node개수
//correct!
#include<iostream>
using namespace std;
class Node {
private:
int data;
Node* par;
Node* left;
Node* right;
public: Node(int data) {
this->data = data;
this->par = NULL;
this->left = NULL;
this->right = NULL;
}
void setLeft(Node* node) {
if (node == NULL) {
this->left = NULL;
}
else {
this->left = node;
node->par = this; //이해가 좀 안가넴 ..흠
}
}
void setRight(Node* node) {
if (node == NULL) {
this->right = NULL;
}
else {
this->right = node;
node->par = this;
}
}
friend class BST;
};
class BST {
public:
Node* root;
BST() {
this->root = NULL;
}
Node* search(int data) { //탐색연산 (찾으려는 노드가 있으면 그 노드를 리턴)
Node* curN = this->root;
while (curN != NULL) {
if (curN->data == data) {
return curN;
}
else if (data > curN->data) curN = curN->right;
else curN = curN->left;
}
return NULL;
}
void insert(int data) { //삽입연산
Node* node = new Node(data); //삽입할 노드
if (this->root == NULL) { //빈 트리일 경우
this->root = node; //루트에 삽입하고
return; //함수종료
}
//삽입해야할 위치찾기
Node* parN = NULL;
Node* curN = this->root;
while (curN != NULL) {
if (curN->data < data) {
parN = curN;
curN = curN->right;
}
else {
parN = curN;
curN = curN->left;
}
}
//찾은 위치에 삽입
if (data > parN->data) parN->setRight(node);
else if (data < parN->data) parN->setLeft(node);
}
void remove(int data) { //삭제연산
Node* node = this->search(data); //삭제할 노드찾기
Node* parN = node->par; //삭제할 노드의 부모노드도 찾기
//삭제할 노드가 루트면!!!!
if (node == root) {
if (root->right == NULL) {
root = root->left;
}
else {
root = root->right;
}
delete node;
return;
}
//삭제할 노드의 자식이 모두 null인 경우
if (node->left == NULL && node->right == NULL) {
if (parN->left == node) {
parN->left = NULL;
}
else {
parN->right = NULL;
}
delete node;
}
//삭제할 노드가 오른쪽자식만 있을 경우
else if (node->left == NULL && node->right != NULL) {
if (parN->left == node) {
parN->left = node->right;
node->right->par = parN;
}
else {
parN->right = node->right;
node->right->par = parN;
}
delete node;
}
//삭제할 노드가 왼쪽 자식만 있을 경우
else if (node->left != NULL && node->right == NULL) {
if (parN->left == node) {
parN->left = node->left;
node->left->par = parN;
}
else {
parN->right = node->left;
node->left->par = parN;
}
delete node;
}
else { //삭제할 노드의 두 자식이 모두 내부노드일 경우
Node* temp = node->right;
while (temp->left != NULL) {
temp = temp->left;
} //temp=석세서
int x = node->data;
node->data = temp->data; //원래 삭제할 노드에 석세서값 덮어씌우기
temp->data = x; //석세서에 삭제할 값 덮어씌우기, 이제 이 석세서를 삭제하는 거!
//석세서의 왼쪽은 무조건 NULL이므로 오른쪽만 확인하면 됨.
if (temp->right != NULL) {
if (temp->par == node) //석세서의 부모가 삭제할 노드일 경우
{
node->right = temp->right;
temp->right->par = node;
}
else
{
temp->par->left = temp->right;
temp->right->par = temp->par;
}
}
else { //석세서 자식이 없으면 석세서자리 null로 바꿔주깅.
if (temp->par == node) {
node->right = NULL;
}
else {
temp->par->left = NULL;
}
}
temp = NULL;
}
}
int sub(int data){
Node* node = this->search(data);
if (node == NULL) {
return 0;
}
int count = 0;
if (node->left != NULL) {
count += sub(node->left->data);
}
count++;
if (node->right != NULL) {
count += sub(node->right->data);
}
return count;
}
};
int main() {
int T;
cin >> T;
string oper; int x;
BST tree;
for (int i = 0; i < T; i++) {
cin >> oper;
if (oper == "insert") {
cin >> x;
tree.insert(x);
}
else if (oper == "delete") {
cin >> x;
tree.remove(x);
}
else if (oper == "sub") {
cin >> x;
cout << tree.sub(x) << endl;
}
else {
cout << "다시" << endl;
}
}
}