반응형




< main.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
#include <stdio.h>
#include <iostream>
#include "BinaryTree.h"
 
using namespace std;
 
BTreeNode *tree[1000= { NULL, };
extern int chkTree;
extern int findNode;
 
 
int main()
{
    int num, value;
 
    while (1)
    {
        cout << "1.삽입\n2.삭제\n3.탐색\n4.전위 순회\n5.중위 순회\n6.후위 순회\n7.종료\n";
        cout << "번호를 입력하세요 :: "cin >> num;
 
        switch (num)
        {
            case 1cout << "삽입 할 값을 입력하세요 :: "cin >> value; chkTree = 1; MakeSubTree(value); break;
            case 2: DelTree(); break;
            case 3:
                cout << "탐색 할 값을 입력하세요 :: "cin >> value; 
                PreTraverseSearch(tree[0], value);
                if (findNode == 1)
                {
                    cout << "탐색 값이 존재합니다." << endl;
                    findNode = 0;
                }
                else
                    cout << "탐색 값이 존재하지 않습니다." << endl;
                
                cout << endl; 
                break;
 
            case 4:    PreorderTraverse(tree[0], ShowData); cout << endl; break;
            case 5: InorderTraverse(tree[0], ShowData); cout << endl; break;
            case 6: PostorderTraverse(tree[0], ShowData); cout << endl; break;
            case 7: exit(0);
        }
    }
    
 
    return 0;
}
Crocus






< BinaryTree.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
#include <stdio.h>
#include <stdlib.h>
#include "BinaryTree.h"
 
/*
함수들의 실제 내용을 적어 놓은 곳
*/
 
extern BTreeNode *tree[1000];
 
int f = 0, b = 1;
int cnt = 1;
int chkTree;
int findNode = 0;
 
BTreeNode *MakeBTreeNode(void)
{
    BTreeNode *nd = (BTreeNode *)malloc(sizeof(BTreeNode));
    nd->left = NULL;
    nd->right = NULL;
    return nd;
}
 
void ShowData(int data)
{
    printf("%d ", data);
}
 
 
void PreTraverseSearch(BTreeNode *bt, int value)
{
    if (bt == NULL)
        return ;
 
    if (bt->data == value)
    {
        findNode = 1;
    }
 
    PreTraverseSearch(bt->left, value);
    PreTraverseSearch(bt->right, value);
}
 
void DelTree()
{
    if (chkTree == 0)
    {
        printf("Tree가 존재하지 않습니다.\n");
        return;
    }
    else if (b == 1)
    {
        printf("Root 노드 %d 를 지웁니다.\n",tree[0]->data);
        tree[0]->left = NULL;
        tree[0]->right = NULL;
        tree[0]->data = NULL;
        tree[0= NULL;
        free(tree[0]);
        chkTree = 0;
    }
    else if (cnt % == 0)
    {
        chkTree = 1;
        if (tree[f]->right == tree[b - 1])
        {
            printf("오른쪽 %d 를 지웁니다. 현재 이것의 부모 노드는 %d 입니다.\n", tree[b - 1]->data,tree[f]->data);
            tree[f]->right = NULL;
            free(tree[b - 1]);
            b--;
        }
 
        else if (tree[f]->left == tree[b - 1])
        {
            printf("왼쪽 %d 를 지웁니다. 현재 이것의 부모 노드는 %d 입니다.\n", tree[b - 1]->data,tree[f]->data);
            tree[f]->left = NULL;
            free(tree[b - 1]);
 
            b--;
            f--;
        }
 
    }
    else if (cnt % == 1)
    {
        chkTree = 1;
        if (tree[f - 1]->right == tree[b - 1])
        {
            printf("오른쪽 %d 를 지웁니다. 현재 이것의 부모 노드는 %d 입니다.\n", tree[b - 1]->data, tree[f-1]->data);
            tree[f - 1]->right = NULL;
            free(tree[b - 1]);
            b--;
        }
 
        else if (tree[f - 1]->left == tree[b - 1])
        {
            printf("왼쪽 %d 를 지웁니다. 현재 이것의 부모 노드는 %d 입니다.\n", tree[b - 1]->data, tree[f-1]->data);
            tree[f - 1]->left = NULL;
            free(tree[b - 1]);
 
            b--;
            f--;
        }
    }
 
}
void MakeSubTree(int value)
{
    if (tree[0== NULL) // tree[0] == root
    {
        tree[0= MakeBTreeNode();
        SetData(tree[0], value);
    }
    else
    {
        tree[b] = MakeBTreeNode();
        SetData(tree[b], value);
                
        if (cnt % == 1)
        {
            MakeLeftSubTree(tree[f], tree[b]);
            cnt++;
            b++;
        }
 
        else if (cnt % == 0)
        {
            MakeRightSubTree(tree[f], tree[b]);
            cnt++;
            f++;
            b++;
        }
    }
}
 
void SetData(BTreeNode *bt, BTData data)
{
    bt->data = data;
}
 
void MakeLeftSubTree(BTreeNode *main, BTreeNode *sub)
{
    if (main->left != NULL)
        free(main->left);
 
    main->left = sub;
}
 
void MakeRightSubTree(BTreeNode *main, BTreeNode *sub)
{
    if (main->right != NULL)
        free(main->right);
 
    main->right = sub;
}
 
 
 
void PreorderTraverse(BTreeNode *bt, VisitFuncPtr action)
{
    if (bt == NULL)
        return;
 
    action(bt->data);
    PreorderTraverse(bt->left, action);
    PreorderTraverse(bt->right, action);
}
 
void InorderTraverse(BTreeNode *bt, VisitFuncPtr action)
{
    if (bt == NULL)
        return;
 
    InorderTraverse(bt->left, action);
    action(bt->data);
    InorderTraverse(bt->right, action);
}
 
void PostorderTraverse(BTreeNode *bt, VisitFuncPtr action)
{
    if (bt == NULL)
        return;
 
    PostorderTraverse(bt->left, action);
    PostorderTraverse(bt->right, action);
    action(bt->data);
}
Crocus







< BinaryTree.h >


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
#pragma once
 
/*
구조체 및 함수들에 대한 정의를 수록
*/
typedef int BTData;
 
typedef struct _bTreeNode
{
    BTData data;
    struct _bTreeNode *left;
    struct _bTreeNode *right;
}BTreeNode;
 
BTreeNode *MakeBTreeNode(void);
void MakeSubTree(int value);
void DelTree();
 
void SetData(BTreeNode *bt, BTData data);
 
 
void MakeLeftSubTree(BTreeNode *main, BTreeNode *sub);
void MakeRightSubTree(BTreeNode *main, BTreeNode *sub);
 
typedef void VisitFuncPtr(BTData data); // == void (*VisitFuncPtr)(BTData data);
void ShowData(int data);
 
void PreorderTraverse(BTreeNode *bt, VisitFuncPtr action); // 전위 순회
void InorderTraverse(BTreeNode *bt, VisitFuncPtr action); // 중위 순회
void PostorderTraverse(BTreeNode *bt, VisitFuncPtr action); // 후위 순회
void PreTraverseSearch(BTreeNode *bt, int value);
Crocus




일단 널리 알려진 이진 탐색 트리와는 다르다는 것을 명시하고자 한다.


이 코드는 어떤 값에도 관계없이 순서대로 노드에 값이 달린다.


그에 관한 코드는 http://www.crocus.co.kr/350 에서 사용한 코드를 응용하였다.


즉 배열 포인터로 만들어서 이용하였다. (배열 포인터 = 이중 포인터)


앞서 설명된 이진 트리의 개념을 기반으로 모든 것을 작성하였기에, 게시글들의 내용을 읽는다면 해석하기 쉬울 것이다.


(필자 또한 자료구조를 공부하고 있는 상태이다.)


그리고 각 순회에 action이라는 함수 포인터가 있는데, 이것을 이용하기 싫다면


printf("%d ", bt->data);를 이용하여도 무방하다.



삭제 및 삽입 구현과정에서 f, b, cnt라는 변수를 이용하였는데 f는 현재 노드 바로 위의 노드를 의미한다.(각각의 부모노드


b는 현재 노드를 의미하고, cnt는 그다음 트리에 달릴 노드가 왼쪽인지 오른쪽인지 구분하는 과정에서 이용하였다


탐색의 경우에는 전위 순회방식을 이용하여 탐색하도록 만들었다


전위, 중위, 후위 순회는 하나의 전위 순회 코드를 작성하여 순서를 바꾸며 전위, 중위, 후위 순회를 만들었다.  




반응형