컴공 일기197
게시글 주소: https://dev.orbi.kr/00059098866

순차탐색은 일단, 시간복잡도가 O(N)인 반면... 이진 탐색은 시간복잡도가 O(Log2N)이기 때문에 훨씬 성능이 좋은 알고리즘이라 할 만합니다. 다만 문제는, 배열로 데이터가 주어진 경우에는 인덱스를 통해서 중앙 요소의 데이터를 구할 수 있고 이를 토대로 간단히 구현 가능하지만, 만약 구조가 링크드 리스트라면, "중앙 요소"를 쉽게 찾아낼 수 없게 된다는 것입니다. 그래서, 링크드리스트 속에서도 이 중앙요소를 판별하기 위해 사용하는 자료구조가 있으니, 그것이 바로 이진 탐색 트리(Binary Search Tree)가 되겠습니다. 이 구조에는 중앙요소를 쉽게 판별하기 위해서 정한 규칙이 몇 가지 있는데, 그건 넘어가도록 하겠습니다. 궁금하시면, 찾아보셔요! 간단하게 말하면, 순열처럼 자료의 크기에 따라 위치시켜야 하는 장소가 정해져 있습니다. 그래야, 중앙에 위치하게 되는 데이터가 무엇인지 알아낼 수 있겠지요? 다음 그림이 바로 그 규칙을 토대로 생성한 이진 탐색 트리의 구조입니다.
여하튼 다시 본론으로 돌아가서, 이진 탐색 트리는 링크드리스트에서 중앙요소를 찾아내기에 굉장히 용이한 자료구조라고 보면 됩니다. 이것을 이용하면, 링크드리스트에서도 얼마든지 이진 탐색이라는 고성능의 알고리즘을 사용할 수 있다는 것입니다. 결국 이진 탐색은 중앙 요소를 경계로 하여 빠르게 원소들을 분별하는 것이 핵심이니까요.
다음은 그냥 예제 코드입니다.
헤더파일 : "Binary.h"
#pragma once
#ifndef BINARY_SEARCH_TREE_H
#define BINARY_SEARCH_TREE_H
#include <stdio.h>
#include <stdlib.h>
typedef struct tagBSTNode
{
struct tagBSTNode* Left;
struct tagBSTNode* Right;
int Data;
}BSTNode;
BSTNode* BST_CreateNode(int Newdata);
void BST_DestroyNode(BSTNode* Node);
void BST_DestroyTree(BSTNode* Tree);
BSTNode* BST_SearchNode(BSTNode* Tree, int Target);
BSTNode* BST_SearchMinNode(BSTNode* Tree);
void BST_InsertNode(BSTNode* Tree, BSTNode* Child);
BSTNode* BST_RemoveNode(BSTNode* Tree, BSTNode* Parent, int Target);
void BST_InorderPrintTree(BSTNode* Node);
#endif
BinarySearchTree.c
#include "Binary.h"
BSTNode* BST_CreateNode(int NewData)
{
BSTNode* NewNode = (BSTNode*)malloc(sizeof(BSTNode));
NewNode->Left = NULL;
NewNode->Right = NULL;
NewNode->Data = NewData;
return NewNode;
}
void BST_DestroyNode(BSTNode* Node)
{
free(Node);
}
void BST_DestroyTree(BSTNode* Tree)
{
if (Tree->Right != NULL)
BST_DestroyTree(Tree->Right);
if (Tree->Left != NULL)
BST_DestroyTree(Tree->Left);
Tree->Left = NULL;
Tree->Right = NULL;
BST_DestroyNode(Tree);
}
BSTNode* BST_SearchNode(BSTNode* Tree, int Target)
{
if (Tree == NULL)
return NULL;
if (Tree->Data == Target)
return Tree;
else if (Tree->Data > Target)
return BST_SearchNode(Tree->Left, Target);
else
return BST_SearchNode(Tree->Right, Target);
}
BSTNode* BST_SearchMinNode(BSTNode* Tree)
{
if (Tree == NULL)
return NULL;
if (Tree->Left == NULL)
return Tree;
else
return BST_SearchMinNode(Tree->Left);
}
void BST_InsertNode(BSTNode* Tree, BSTNode* Child)
{
if (Tree->Data < Child->Data)
{
if (Tree->Right == NULL)
Tree->Right = Child;
else
BST_InsertNode(Tree->Right, Child);
}
else if (Tree->Data > Child->Data)
{
if (Tree->Left == NULL)
Tree->Left = Child;
else
BST_InsertNode(Tree->Left, Child);
}
}
BSTNode* BST_RemoveNode(BSTNode* Tree, BSTNode* Parent, int Target)
{
BSTNode* Removed = NULL;
if (Tree == NULL)
return NULL;
if (Tree->Data > Target)
Removed = BST_RemoveNode(Tree->Left, Tree, Target);
else if (Tree->Data < Target)
Removed = BST_RemoveNode(Tree->Right, Tree, Target);
else
{
Removed = Tree;
if (Tree->Left == NULL && Tree->Right == NULL)
{
if (Parent->Left == Tree)
Parent->Left = NULL;
else
Parent->Right = NULL;
}
else
{
if (Tree->Left != NULL && Tree->Right != NULL)
{
BSTNode* MinNode = BST_SearchMinNode(Tree->Right);
MinNode = BST_RemoveNode(Tree, NULL, MinNode->Data);
Tree->Data = MinNode->Data;
}
else
{
/*자식이 하나 있는 경우*/
BSTNode* Temp = NULL;
if (Tree->Left != NULL)
Temp = Tree->Left;
else
Temp = Tree->Right;
if (Parent->Left == Tree)
Parent->Left = Temp;
else
Parent->Right = Temp;
}
}
}
return Removed;
}
void BST_InorderPrintTree(BSTNode* Node)
{
if (Node == NULL)
return;
BST_InorderPrintTree(Node->Left);
printf("%d ", Node->Data);
BST_InorderPrintTree(Node->Right);
}
main.c
#include "Binary.h"
int main(void)
{
BSTNode* Tree = BST_CreateNode(123);
BSTNode* Node = NULL;
//이진 탐색 트리 규율에 맞게 노드 생성
BST_InsertNode(Tree, BST_CreateNode(22));
BST_InsertNode(Tree, BST_CreateNode(9918));
BST_InsertNode(Tree, BST_CreateNode(424));
BST_InsertNode(Tree, BST_CreateNode(17));
BST_InsertNode(Tree, BST_CreateNode(3));
BST_InsertNode(Tree, BST_CreateNode(98));
BST_InsertNode(Tree, BST_CreateNode(34));
BST_InsertNode(Tree, BST_CreateNode(760));
BST_InsertNode(Tree, BST_CreateNode(317));
BST_InsertNode(Tree, BST_CreateNode(1));
BST_InorderPrintTree(Tree);
printf("\n");
printf("Removing 98....\n");
Node = BST_RemoveNode(Tree, NULL, 98);
BST_DestroyNode(Node);
BST_InorderPrintTree(Tree);
printf("\n");
printf("Inserting 111...\n");
BST_InsertNode(Tree, BST_CreateNode(111));
BST_InorderPrintTree(Tree);
printf("\n");
BST_DestroyTree(Tree);
return 0;
}
코드 실행 결과 :
1 3 17 22 34 98 123 317 424 760 9918
Removing 98....
1 3 17 22 34 123 317 424 760 9918
Inserting 111...
1 3 17 22 34 111 123 317 424 760 9918
0 XDK (+0)
유익한 글을 읽었다면 작성자에게 XDK를 선물하세요.
-
오르비문학 1화 0 0
오르비문학 1화
-
Test 0 0
Tetsteyey
-
수학 4등급만 받으면 2 0
쫀득하게 인서울 할 수 있는데
-
엘든링 왜 자꾸 멈추지 1 0
컴퓨터 좋은건데 씨발
-
목 졸라줘 5 1
켁켁켁 숨막혀 ㅜㅜ
-
시험지에 따라서 난이도가 가장 극단적으로 달라지는 번호같음....
-
개쉽게 풀리는데 이거 맞나
-
정시로 갑시다 8 0
내신반영을 노려서 내신 깡패 정시러
-
나왔어 12 0
다시감 근데 저게 왜 이륙햇냐
-
갑자기생각난썰 1 1
고1 2학기 학급회장선거때 후보가 2명이엇는데 그 친구들 둘이 합의하고 한명이...
-
그만하고 잘까 1 0
흐름이 끊겨버렷네
-
세기말 수능 1 1
2000학년도 대학수학능력시험
-
강은양t 0 0
현역 고3이고 작년까지 모고 3~4등급 나왔는데 지금부터 강은양t 들으려고 합니다....
-
2시열차 1 0
출발
-
지금 강민철 현강 다니고 있는데 저랑 너무 안맞는 느낌이 심하게 들어서...
-
뭘 해야하나요 0 0
이번에 고등학교 2학년 된 이공계 지망하는 지방 일반고학생입니다. 생기부를 제대로...
-
이게 오르비를 재밌게 오래하려면 10 4
수험생활을 지속해야 함
-
에ㅔㅔㅔㅔㅔㅔㄴ들리스레인ㄴㄴ 0 1
폴온마이헐트 코코로노 키즈니ㅣㅣㅣ
-
내 이상형 중단발에 속눈썹 1 0
-
우와 보추야동 많이떴다 2 2
보다자야지
-
심심한데 무물보 5 0
응애 나 아가학생
-
본인 물1 점수 꼬라지 0 1
3모 48점 (99) 5더프 47점인가였는데 시험이 어려웠어서 전국석차 30등쯤...
-
오후8시부터자다가깼더니 1 0
다시잠이안오네.. 비상..!!
-
생각나는구나
-
ㅇㄴ근데 0학점 패논패과목을 오ㅑㄹ케 빡세게시켜 0 0
그냥 좀 봐주면 안되나
-
시발점 한 다음 스블 0 0
고2이고대수 개념원리, 쎈, 고쟁이 했습니다개정 시발점 사놓은 게 있어서...
-
러셀 외부생 더프 성적표 0 0
문자로 발송되나요?? 아님 직접 찾으러 가야햐나요??
-
원래 사람은 별을 쫓아 달려갈 때 가장 빛나는 법이여설령 닿지 못할지라도적어도 내...
-
저걸 어케 함 진짜 와.. 원과목 중 생1만 수능공부로 안해봤는데 안하길잘한듯
-
시발 나 개폐급임 2 1
조별과제 하는족족 내것만 교수님 피드백 나오고 술처먹다 팀원들한테 자료 제출 개늦게하고 자퇴마렵다
-
딱 한 마디만 하고 자러감 9 3
미쿠 ㅈㄴ 예뻐어~~~~~~~~~~~~
-
중앙대 가기 59일차 3 1
안녕하세요 중앙대29학번 부산사나이 이동현입니다 음 오늘이 벌써 59일차군요...
-
이제 좀 자보실까 11 1
음음
-
리젠존나느리네 1 0
오르비망함?
-
너무멍청해짐 1 0
ㅜㅜㅜㅜㅜ
-
생윤 진짜 1도 모르는 쌩노베인데 누구 듣는 게 좋을가여
-
15살과 엄마 그 사이는 2 0
뭐라함 급함
-
대신 연세대 가겠다 선언
-
작년 10모 20번 0 0
이렇게 푸는거 맞나..?
-
위키하우 도움 ㅈㄴ 안되네 6 0
ㅗㅗㅗㅗㅗㅗ
-
새르비 할수록 4 0
헛소리가 늘어가는듯
-
아니 난 신라면 쳐돌이라 5 0
신라면만 먹는데….
-
내가사실은생명과학을좋아함 1 0
수능말고 그냥생명과학
-
. 11 1
-
님들 최애 과목 말해보셈 7 0
난 국어
-
님들 최애 라면 말해보셈 10 0
난 신라면
-
라면이랑 과자 안먹은지 6일차 2 0
후후

하지만 node의 삽입/삭제가 빈번해서 skewed 이슈가 발생하거나 그걸 해결하기 위한 balancing 연산량이 일정량 이상 필요할경우 순차탐색이 나을수도
구현이 간단하기도 할 것이구요...! 아무래도 알고리즘이라는 건 역시 때에 따라 잘 '선택하여 사용'하는 것이 중요한 것 같아요 ㅎㅎ