VioletaBabel

트리 본문

기본개념/알고리즘공부
트리
Beabletoet 2017. 9. 8. 22:48

트리


트리는 그래프의 일종. 허나 사이클이 없다.


트리는 하나의 루트 노드를 가진다.

루트 노드는 0개 이상의 자식 노드를 가지고 있다.

자식 노드는 0개 이상의 자식 노드를 가지고 있다. 이는 반복된다.



--

이진 트리는 각 노드가 최대 둘의 자식을 가지는 트리이다.


이진 탐색 트리는 왼쪽 자식들 <= 부모 노드 < 오른쪽 자식들을 모든 노드에 만족하는 이진 트리이다.

허나, 중복된 값과 좌우의 문제는 갈릴 수 있음.



--

완전 이진 트리(complete binary tree)

마지막 단계를 제외한 모든 노드가 채워져 있으며, 마지막 단계도 왼쪽에서 오른쪽으로 채워져있는 이진 트리.


전 이진 트리(full binary tree)

모든 노드의 자식이 없거나, 둘인 이진 트리이다.


포화 이진 트리(perfect binary tree)

전 이진 트리이면서 완전 이진 트리인 경우.

모든 말단 노드는 같은 높이에 있으며, 마지막 단계에서 노드의 개수도 최대여야 한다.

실제 상황에서 흔한 케이스는 아니다.



--

이진 트리 순회


중위 순회(in-order)

좌-중-우 순회



전위 순회(pre-order)

중-좌-우 순회



후위 순회(post-order)

좌-우-중 순회


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
#include <cstdio>
struct node
{
    node *left;
    node *right;
    int data;
};
node *root, *leaf;
void init();
void in(node *r);
void post(node *r);
void pre(node *r);
int main()
{
    init();
    int command;
    while (1)
    {
        printf("1-pre / 2-in / 3-post / 4-exit\n : ");
        scanf("%d"&command);
        switch (command)
        {
        case 1: pre(root); break;
        case 2: in(root); break;
        case 3: post(root); break;
        case 4return 1;
        }
        printf("\n");
    }
 
}
void init()
{
    root = new node;
    leaf = new node;
    root->left = new node;
    root->right = new node;
    root->left->left = new node;
    root->left->right = new node;
    root->right->left = new node;
    root->right->right = new node;
    root->left->left->left = leaf;
    root->left->left->right = leaf;
    root->left->right->left = leaf;
    root->left->right->right = leaf;
    root->right->left->left = leaf;
    root->right->left->right = leaf;
    root->right->right->left = leaf;
    root->right->right->right = leaf;
    root->data = 4;
    root->left->data = 2;
    root->right->data = 6;
    root->left->left->data = 1;
    root->left->right->data = 3;
    root->right->left->data = 5;
    root->right->right->data = 7;
    leaf->data = -1;
}
void in(node *r)
{
    if(r->left->data != -1)
        in(r->left);
    printf("%d   ", r->data);
    if(r->right->data != -1)
        in(r->right);
}
void post(node *r)
{
    if (r->left->data != -1)
        post(r->left);
    if (r->right->data != -1)
        post(r->right);
    printf("%d   ", r->data);
}
void pre(node *r)
{
    printf("%d   ", r->data);
    if (r->left->data != -1)
        pre(r->left);
    if (r->right->data != -1)
        pre(r->right);
}
cs


-----

이진 힙


최소 힙과 최대 힙이 있다.

최소 힙은 가장 낮은 수가 루트이며 리프로 갈수록 수가 커진다.

최대 힙은 가장 높은 수가 루트이며 리프로 갈수록 수가 커진다.



최소 힙 코드


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
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
int main()
{
    vector<int> heap;
    int num;
    char command;
    while (1)
    {
        printf("입력 - i / 삭제 - d\n : ");
        scanf("%c"&command);
        if (command == 'i')
        {
            printf("입력할 자연수 : ");
            scanf("%d"&num);
            heap.push_back(num);
            for (int i = heap.size() - 1; i > 0; i = (i+1)/2 - 1)
                if (heap[i] < heap[((i + 1/ 2- 1])
                    swap(heap[i], heap[((i + 1/ 2- 1]);
        }
        else if (command == 'd')
        {
            if (!heap.empty())
            {
                printf("%d\n", heap.front());
                swap(heap.front(), heap.back());
                heap.pop_back();
                for (int i = 0; i < heap.size();)
                {
                    if (i * 2 + 3 <= heap.size())
                    {
                        if (heap[i * 2 + 1> heap[i * 2 + 2])
                        {
                            if (heap[i] > heap[i * 2 + 2])
                                swap(heap[i], heap[i * 2 + 2]);
                            i = i * 2 + 2;
                        }
                        else
                        {
                            if (heap[i] > heap[i * 2 + 1])
                                swap(heap[i], heap[i * 2 + 1]);
                            i = i * 2 + 1;
                        }
                    }
                    else if (i * 2 + 2 == heap.size())
                    {
                        if (heap[i] > heap[i * 2 + 1])
                            swap(heap[i], heap[i * 2 + 1]);
                        i = i * 2 + 1;
                    }
                    else
                        break;
                }
            }
        }
        while (getchar() != '\n');
    }
}
cs


'기본개념 > 알고리즘공부' 카테고리의 다른 글

비트 조작  (0) 2017.09.11
그래프  (0) 2017.09.09
  (0) 2017.09.08
스택  (0) 2017.09.08
연결리스트  (0) 2017.09.08
Comments