반응형
중복 키가 없는 이진트리 구현하기
1. 메쏘드
i : key 입력 받은 후 트리에 삽입
d : key 입력 받은 후 해당 노드가 있다면 노드 삭제, 삭제한 키 출력. 없으면 X 출력
s : key 입력 받은 후 해당 노드가 있다면 키를 출력, 없으면 X 출력
p : 트리를 전위 순회로 인쇄.
q : 종료
2. 메소드 구현
[public]
* findElement(k) : key를 받아서 해당 노드를 찾아 원소를 반환(여기서 원소 = 키)
* insertItem(k) : key를 받아서 트리에 해당 키를 가진 노드를 삽입.
treesearch , setnode , expandExternal(left), expandExternal(right).
treesearch , setnode , expandExternal(left), expandExternal(right).
* treeSearch(w, k) : (노드, 키) 트리에서 원하는 키를 가진 노드를 반환하되 없어도 위치할 위치의 외부노드를 반환.
* removeElement(k) : 키를 입력받아서 해당 위치의 노드를 삭제하고, 원소를 반환 (여기서 원소 = 키)
treeSearch, left right 둘 중 하나라도 외부노드이면 reduce External, 둘다 내부노드이면 inOrderSucc(w), leftchild에 대해
treeSearch, left right 둘 중 하나라도 외부노드이면 reduce External, 둘다 내부노드이면 inOrderSucc(w), leftchild에 대해
* isExternal(w) : 노드가 외부노드인지 내부노드인지 반환.
* inOrderSucc(w) : w노드의 중위순위 후계자를 반환(중위순회시 루트 이후에 가장 먼저 방문할 노드. 오른쪽 부트리중 가장 왼쪽 말단의 내부노드)
* ft_handle_error() : 에러 시 출력 후 exit
[private]
* init_tree : tree 초기화.
* expandExternal : 해당 노드를 외부노드로 확장. 부모 설정도 해줘야 함.
* leftchild, rightchild(w) : 해당노드의 왼쪽, 오른쪽 자식을 반환
* reduceExternal(w)
* 외부노드인 w를 입력받고 parent를 삭제하되, w의 자식은 grand와 이어주고 나서 삭제한다. (w도 삭제)!
* Sibling(w):
* w의 형제노드를 반환한다. (외부노드이든 내부노드이든)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define TRUE 1
#define FALSE 0
#define NO_SUCH_KEY -1
struct node_
{
int key;
struct node_ *lchild;
struct node_ *rchild;
struct node_ *parent;
};
typedef struct node_ node;
struct tree_ {
node *root;
};
typedef struct tree_ Tree;
void ft_handle_error(char *str)
{
printf("%s", str );
exit(1);
}
node *leftChild(node *w)
{
return w->lchild;
}
node *rightChild(node *w )
{
return w->rchild;
}
int isExternal(node *w)
{
if (w->lchild == NULL && w->rchild == NULL)
return TRUE;
else
return FALSE;
}
node *treeSearch(node *w, int key)
{
if (isExternal(w))
return w;
if(w->key == key)
return w;
else if(key > w->key)
return treeSearch(rightChild(w), key);
else
return treeSearch(leftChild(w), key);
}
node *get_sibling(node *w)
{
node *p = w->parent;
node *ws;
if (p == NULL)//root이면
return NULL;//형제가 없다
if(leftChild(p) == w)
return rightChild(p);
else if(rightChild(p) == w)
return leftChild(p);
else
return NULL;
}
node *reduceExternal(node *w)
{
node *p = w->parent;
node *sibling = get_sibling(w);
if(p->parent == NULL)//루트라면
{
*p = *sibling;
p->parent = NULL;
}
else {
node *g = p->parent;
sibling->parent = g;
if (leftChild(g) == p)
g->lchild = sibling;
else if (rightChild(g) == p)
g->rchild = sibling;
free(p);
}
free(w);
return sibling;
}
void expandExternal(node *w)
{
w->lchild = (node *)malloc(sizeof(node));
if(!w->lchild)
ft_handle_error("malloc failed.\n");
w->lchild->lchild = NULL;
w->lchild->rchild = NULL;
w->lchild->parent = w;
w->rchild = (node *)malloc(sizeof(node));
if(!w->rchild)
ft_handle_error("malloc failed.\n");
w->rchild->lchild = NULL;
w->rchild->rchild = NULL;
w->rchild->parent = w;
}
void setnode(node *w, int key)
{
w->key = key;
}
int insertItem(Tree *tree, int key)
{
node *w = treeSearch(tree->root, key);
if (!isExternal(w))
return 0;
setnode(w, key);
expandExternal(w);
return 1;
}
node *inOrderSucc(node *w)
{
if (isExternal((w)) || isExternal(w->rchild)|| !w)
ft_handle_error("wrong node input ");
node *find = w->rchild;
node *save = find;
while(!isExternal((find)))
{
save = find;
find = find->lchild;
}
return save;
}
int findElement(Tree *tree, int key)
{
node *w = treeSearch(tree->root, key);
if (isExternal(w)) {
return NO_SUCH_KEY;
}
else
return w->key;
}
int removeElement(Tree *tree, int key) {
node *w = treeSearch(tree->root, key);
node *z;
int element;
if (isExternal(w))
return NO_SUCH_KEY;
element = w->key;
node *v = leftChild(w);
if(!isExternal(v))
v = rightChild((w));
if(isExternal(v))
reduceExternal(v);
else
{
v = inOrderSucc((w));
z = leftChild(v);
setnode(w, v->key);
reduceExternal(leftChild(v));
}
return element;
}
void print_tree(node *w)
{
if (isExternal(w))
return ;
printf("%d ", w->key);
print_tree(leftChild(w));
print_tree(rightChild(w));
}
void init_tree(Tree **tree)
{
*tree = (Tree *)malloc(sizeof(tree));
(*tree)->root = (node *)malloc(sizeof(node));
(*tree)->root->parent = NULL;
}
void free_node(node * w)
{
if(isExternal(w))
free(w);
free_node(leftChild(w));
free_node(rightChild(w));
}
void ft_free(Tree *tree)
{
free_node(tree->root);
free(tree);
}
int main()
{
Tree *tree;
int key, result;
char menu;
node *n;
init_tree(&tree);
while(1)
{
scanf("%c", &menu);
switch(menu)
{
case 'i' :
scanf("%d", &key);
if (!insertItem(tree, key))
ft_handle_error("insert failed.\n");
break;
case 'd':
scanf("%d", &key);
if((result = removeElement(tree, key)) != NO_SUCH_KEY)
printf("%d\n", result);
else
printf("X\n");
break;
case 's':
scanf("%d", &key);
if(!isExternal( n= treeSearch(tree->root, key)))
printf("%d\n", n->key);//노드의 데이터 출력
else
printf("X\n");
break;
case 'p':
print_tree(tree->root);
printf("\n");
break;
case 'q':
//ft_free(tree);
return 0;
}
}
}
반응형
'개발 > C,C++' 카테고리의 다른 글
🟡cpp 문법 - 파싱에 필요한 몇 가지 string 관련 함수들 (0) | 2023.06.14 |
---|---|
[C++] iterator에 대하여 (반복자) (1) | 2023.06.12 |
[알고리즘]최소신장트리 (MST)구현하기 - C로구현하기 (2) | 2022.12.17 |
C - 인접행렬로 그래프 구현하기 (알고리즘) (0) | 2022.12.16 |
해쉬테이블 구현하기(C, C언어) (0) | 2022.12.16 |