Notice
Recent Posts
Recent Comments
Link
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 프로그래머스
- C
- 데이터베이스
- 인접 행렬
- 코테공부
- 오블완
- 갭체크
- 개발자취업
- 99클럽
- 개발자루틴
- 코드트리
- 자료구조
- 코딩테스트준비
- Java
- 1일1코테
- 플로이드-워셜
- til
- 프로그래밍 언어
- 항해99
- 코딩테스트사이트추천
- 알고리즘
- 티스토리챌린지
- 연결 리스트
- 코딩테스트
- #코드트리 #코딩테스트 #코테공부 #백트래킹 #알고리즘 기초
- 운영체제
- 웹
- 자바스크립트
- 자바
- 파이썬
Archives
- Today
- Total
와드의 블로그
11. 탐색 1 본문
※ 해당 글은 C언어에 대한 이해를 필요로 합니다. C 언어에 대해 알고 싶으신 분들은 다음 글을 참고하세요
'프로그래밍 언어/C' 카테고리의 글 목록
ward.tistory.com
(1) 탐색의 이해와 보간 탐색
* 탐색의 이해
탐색은 데이터를 어떻게 찾을까를 고민하는 것이 아닌 효율적인 탐색을 위한 저장 방법에 대해 고민하는 것이다.
주로 트리를 이용하여 탐색을 한다.
* 보간 탐색
보간 탐색은 정렬된 배열에서 범위를 줄여가며 탐색하는 방법이다. 이진 탐색과 비슷하지만 탐색의 위치를 결정하는 방법이 다르다.
보간 탐색의 탐색 위치: s = (x - arr[low]) / (arr[high] - arr[low]) * (high - low) + low
보간 탐색의 구현
int ISearch(int arr[], int first, int last, int target) {
if (arr[first] > target || arr[last] < target)
return -1;
int mid = ((double)(target - arr[first]) / (arr[last] - arr[first]) * (last - first)) + first;
if (arr[mid] == target)
return mid;
else if (target < arr[mid])
return ISearch(arr, first, mid - 1, target);
else
return ISearch(arr, mid + 1, last, target);
}
(2) 이진 탐색 트리
* 이진 탐색 트리의 이해
이진 탐색 트리의 조건
- 각 노드의 왼쪽 서브 트리에는 해당 노드의 값보다 작은 값을 지닌 노드들로 이루어져 있다.
- 각 노드의 오른쪽 서브 트리에는 해당 노드의 값보다 큰 값을 지닌 노드들로 이루어져 있다.
- 중복된 노드가 없어야 한다.
- 왼쪽 서브 트리, 오른쪽 서브 트리 또한 이진 탐색 트리이다.
* 이진 탐색 트리의 구현
#include <stdio.h>
#include "BinaryTree2.h"
typedef BTData BSTData;
void BSTMakeAndInit(BTreeNode** pRoot) {
*pRoot = NULL;
}
BSTData BSTGetNodeData(BTreeNode* bst) {
return GetData(bst);
}
void BSTInsert(BTreeNode** pRoot, BSTData data) {
BTreeNode* pNode = NULL;
BTreeNode* cNode = *pRoot;
BTreeNode* nNode = NULL;
while (cNode != NULL) {
if (data == GetData(cNode))
return;
pNode = cNode;
if (GetData(cNode) > data)
cNode = GetLeftSubTree(cNode);
else
cNode = GetRightSubTree(cNode);
}
nNode = MakeBTreeNode();
SetData(nNode, data);
if (pNode != NULL) {
if (data < GetData(pNode))
MakeLeftSubTree(pNode, nNode);
else
MakeRightSubTree(pNode, nNode);
}
else
*pRoot = nNode;
}
BTreeNode* BSTSearch(BTreeNode* bst, BSTData target) {
BTreeNode* cNode = bst;
BSTData cd;
while (cNode != NULL) {
cd = GetData(cNode);
if (target == cd)
return cNode;
else if (target < cd)
cNode = GetLeftSubTree(cNode);
else
cNode = GetRightSubTree(cNode);
}
return NULL;
}
* 이진 탐색 트리의 삭제 구현
삭제의 구현을 위한 이진 트리의 확장
#include <stdio.h>
#include <stdlib.h>
typedef int BTData;
typedef struct _bTreeNode
{
BTData data;
struct _bTreeNode* left;
struct _bTreeNode* right;
} BTreeNode;
BTreeNode* MakeBTreeNode(void)
{
BTreeNode* nd = (BTreeNode*)malloc(sizeof(BTreeNode));
nd->left = NULL;
nd->right = NULL;
return nd;
}
BTData GetData(BTreeNode* bt)
{
return bt->data;
}
void SetData(BTreeNode* bt, BTData data)
{
bt->data = data;
}
BTreeNode* GetLeftSubTree(BTreeNode* bt)
{
return bt->left;
}
BTreeNode* GetRightSubTree(BTreeNode* bt)
{
return bt->right;
}
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);
}
BTreeNode* RemoveLeftSubTree(BTreeNode* bt)
{
BTreeNode* delNode;
if (bt != NULL) {
delNode = bt->left;
bt->left = NULL;
}
return delNode;
}
BTreeNode* RemoveRightSubTree(BTreeNode* bt)
{
BTreeNode* delNode;
if (bt != NULL) {
delNode = bt->right;
bt->right = NULL;
}
return delNode;
}
void ChangeLeftSubTree(BTreeNode* main, BTreeNode* sub)
{
main->left = sub;
}
void ChangeRightSubTree(BTreeNode* main, BTreeNode* sub)
{
main->right = sub;
}
이진 탐색 트리의 삭제 구현
BTreeNode* BSTRemove(BTreeNode** pRoot, BSTData target) {
BTreeNode* pVRoot = MakeBTreeNode();
BTreeNode* pNode = pVRoot;
BTreeNode* cNode = *pRoot;
BTreeNode* dNode;
ChangeRightSubTree(pVRoot, *pRoot);
while (cNode != NULL && GetData(cNode) != target) {
pNode = cNode;
if (target < GetData(cNode))
cNode = GetLeftSubTree(cNode);
else
cNode = GetRightSubTree(cNode);
}
if (cNode == NULL)
return NULL;
dNode = cNode;
if (GetLeftSubTree(dNode) == NULL && GetRightSubTree(dNode) == NULL) {
if (GetLeftSubTree(pNode) == dNode)
RemoveLeftSubTree(pNode);
else
RemoveRightSubTree(pNode);
}
else if (GetLeftSubTree(dNode) == NULL || GetRightSubTree(dNode) == NULL) {
BTreeNode* dcNode;
if (GetLeftSubTree(dNode) != NULL)
dcNode = GetLeftSubTree(dNode);
else
dcNode = GetRightSubTree(dNode);
if (GetLeftSubTree(pNode) == dNode)
ChangeLeftSubTree(pNode, dcNode);
else
ChangeLeftSubTree(pNode, dcNode);
}
else {
BTreeNode* mNode = GetRightSubTree(dNode);
BTreeNode* mpNode = dNode;
int delData;
while (GetLeftSubTree(mNode) != NULL) {
mpNode = mNode;
mNode = GetLeftSubTree(mNode);
}
delData = GetData(dNode);
SetData(dNode, GetData(mNode));
if (GetLeftSubTree(mpNode) == mNode)
ChangeLeftSubTree(mpNode, GetRightSubTree(mNode));
else
ChangeRightSubTree(mpNode, GetRightSubTree(mNode));
dNode = mNode;
SetData(dNode, delData);
}
if (GetRightSubTree(pVRoot) != *pRoot)
*pRoot = GetRightSubTree(pVRoot);
free(pVRoot);
return dNode;
}
참조문헌: 윤성우의 열혈 자료구조
'CS > 자료구조' 카테고리의 다른 글
| 13. 테이블과 해쉬 (0) | 2021.09.23 |
|---|---|
| 12. 탐색 2 (0) | 2021.09.23 |
| 10. 정렬 (0) | 2021.09.14 |
| 9. 우선순위 큐와 힙 (0) | 2021.09.12 |
| 8. 트리 (0) | 2021.09.09 |