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
using System;
 
public class BinarySearchTree<T> where T : IComparable<T>
{
    public class Node
    {
        public T Data;
        public Node Left;
        public Node Right;
 
        public Node(T data)
        {
            Data = data;
            Left = null;
            Right = null;
        }
    }
 
    private Node root;
 
    public BinarySearchTree()
    {
        root = null;
    }
 
    //데이터를 이진 탐색 트리에 삽입.
    public void Insert(T data)
    {
        root = InsertRecursive(root, data);
    }
 
    //재귀적으로 노드를 삽입.
    private Node InsertRecursive(Node current, T data)
    {
        if (current == null)
            return new Node(data); //삽입할 위치에 도달하면 새로운 노드를 생성하고 반환한다.
 
        if (data.CompareTo(current.Data) < 0)
        {
            current.Left = InsertRecursive(current.Left, data); //데이터가 현재 노드의 데이터보다 작으면 왼쪽 자식트리로 이동하여 삽입한다.
        }
        else
        {
            current.Right = InsertRecursive(current.Right, data); //데이터가 현재 노드의 데이터보다 크거나 같으면 오른쪽 자식트리로 이동하여 삽입한다.
        }
 
        return current;
    }
 
    //주어진 데이터가 이진 탐색 트리에 포함되어 있는지 확인한다.
    public bool Contains(T data)
    {
        return ContainsRecursive(root, data);
    }
 
    //노드를 탐색하여 데이터 포함 여부를 확인
    private bool ContainsRecursive(Node current, T data)
    {
        if (current == null)
            return false//탐색할 위치에 도달하면 데이터를 찾지 못한 것이므로 false를 반환한다.
 
        if (data.CompareTo(current.Data) == 0)
        {
            return true//데이터를 찾은 경우 true를 반환한다.
        }
 
        if (data.CompareTo(current.Data) < 0)
        {
            return ContainsRecursive(current.Left, data); //데이터가 현재 노드의 데이터보다 작으면 왼쪽 서브트리로 이동하여 탐색한다.
        }
        else
        {
            return ContainsRecursive(current.Right, data); //데이터가 현재 노드의 데이터보다 크면 오른쪽 서브트리로 이동하여 탐색한다.
        }
    }
 
    //주어진 데이터를 이진 탐색 트리에서 제거
    public void Remove(T data)
    {
        root = RemoveRecursive(root, data);
    }
 
    // 재귀적으로 노드를 제거
    private Node RemoveRecursive(Node current, T data)
    {
        if (current == null)
            return null;
 
        if (data.CompareTo(current.Data) == 0)
        {
            // 제거할 노드를 찾은 경우
            if (current.Left == null && current.Right == null)
            {
                return null;
            }
            else if (current.Left == null)
            {
                return current.Right; // 왼쪽 서브트리가 없는 경우 오른쪽 서브트리를 반환하여 해당 노드를 제거한다.
            }
            else if (current.Right == null)
            {
                return current.Left; // 오른쪽 서브트리가 없는 경우 왼쪽 서브트리를 반환하여 해당 노드를 제거한다.
            }
            else
            {
                // 왼쪽 서브트리와 오른쪽 서브트리가 모두 있는 경우
                T smallestValue = FindSmallestValue(current.Right); // 오른쪽 서브트리에서 가장 작은 값을 찾는다.
                current.Data = smallestValue; // 찾은 가장 작은 값을 현재 노드에 복사한다.
                current.Right = RemoveRecursive(current.Right, smallestValue); // 오른쪽 서브트리에서 가장 작은 값을 제거한다.
                return current;
            }
        }
 
        if (data.CompareTo(current.Data) < 0)
        {
            current.Left = RemoveRecursive(current.Left, data); // 데이터가 현재 노드의 데이터보다 작으면 왼쪽 서브트리로 이동하여 제거한다.
        }
        else
        {
            current.Right = RemoveRecursive(current.Right, data); // 데이터가 현재 노드의 데이터보다 크면 오른쪽 서브트리로 이동하여 제거한다.
        }
 
        return current;
    }
 
    //가장 작은 값을 찾으려면 왼쪽 노드를 계속 찾으면 된다.
    private T FindSmallestValue(Node node = null)
    {
        Node current = node == null ? root : node;
 
        while (current.Left != null)
            current = current.Left; 
 
        return current.Data; 
    }
 
    //가장 작은 값을 찾으려면 오른쪽 노드를 계속 찾으면 된다.
    public T FindMaxValue(Node node = null)
    {
        Node current = node == null ? root : node;
 
        while (current.Right != null)
            current = current.Right; 
 
        return current.Data;
    }
}
 
 
cs

'공부 > 알고리즘 및 기타 공부' 카테고리의 다른 글

Vector2 관련 연산 (C#)  (0) 2023.05.01
노드와 양방향 그래프 표현 (C#)  (0) 2023.04.27
2진수 ~ 16진수 변환 (C#)  (0) 2023.04.25
이진탐색 (C#) 제네릭  (0) 2023.04.24
투 포인터 알고리즘 (C#)  (0) 2023.04.24

+ Recent posts