반응형
학교과제로 풀었던 황제노드찾기. 내부노드를 한 번 씩만 방문해 황제노드를 판별하는 방식이다. 순회 방식은 레벨순회이다.
황제노드 - 자신은 로만노드가 아니지만 자기 아래 자손들이 모두 로만노드인 노드
로만노드 - 자신의 오른쪽과 왼쪽 부트리의 노드 개수 차이가 5 이하인 노드
구글링 해도 황제, 로만노드의 개념이 나오지 않는 것을 보면 교수님이 고안해내신 개념인 것 같다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
typedef struct node {
struct node *left;
struct node *right;
}NODE;
typedef struct {
NODE *root;
}TREE;
// 각 노드의 좌,우 자식 유무에 대한 정보를 담은 함수. initNode를 편리하게 하기 위함
// 예를 들어, NODE_INFO[0][0] == 1 이면 0번(root) 노드의 왼쪽 자식이 있는 것이다.
// NODE_INFO[노드번호][자식번호] 노드번호 0 ~ 28, 자식번호 0 = left, 1 = right
// 노드의 번호는 root부터 선위순회 방문 순서대로 부여했다.
int NODE_INFO[29][2] = { { 1,1 },{ 1,1 },{ 1,1 },{ 1,1 },{ 0,0 },{ 1,1 },{ 0,0 },{ 1,1 },{ 1,1 },{ 0,0 },{ 0,0 },{ 0,0 },{ 0,0 },{ 1,1 },{ 1,1 },{ 0,0 },{ 0,0 },{ 1,1 },{ 0,0 },{ 0,0 },{ 1,1 },{ 0,0 },{ 1,1 },{ 1,1 },{ 0,0 },{ 0,0 },{ 1,1 },{ 0,0 },{ 0,0 } };
int NOW_NODE_NUM = 0;
// 큐 관련 변수
NODE *queue[15];
int front = 0, rear = 0;
int MAX = 15;
// 트리 관련 함수
NODE* initTree();
void linkNode(NODE *, int, int);
NODE* getNode();
int isEmperor(NODE *);
int isRoman(NODE *);
int isExternal(NODE *);
void levelSearch(NODE *);
// 큐 관련 함수
void enQueue(NODE *);
NODE* deQueue();
int isEmpty();
int isFull();
int main() {
TREE t;
t.root = initTree();
levelSearch(t.root);
return 0;
}
NODE* initTree() {
NODE* root = getNode();
linkNode(root, NODE_INFO[NOW_NODE_NUM][0], NODE_INFO[NOW_NODE_NUM][1]);
return root;
}
void linkNode(NODE *n, int left, int right) {
if (left != 0) {
n->left = getNode();
}
if (right != 0) {
n->right = getNode();
}
if (n->left != NULL) {
linkNode(n->left, NODE_INFO[++NOW_NODE_NUM][0], NODE_INFO[NOW_NODE_NUM][1]);
}
if (n->right != NULL) {
linkNode(n->right, NODE_INFO[++NOW_NODE_NUM][0], NODE_INFO[NOW_NODE_NUM][1]);
}
}
NODE* getNode() {
NODE *new_node;
new_node = (NODE *)malloc(sizeof(NODE));
new_node->left = NULL;
new_node->right = NULL;
return new_node;
}
int isEmperor(NODE *n) {
int left = 0, right = 0;
left = isRoman(n->left);
right = isRoman(n->right);
if (left == 0) return 0;
else if (right == 0) return 0;
else if (abs(left - right) <= 5) return 0;
return 1;
}
int isRoman(NODE *n) {
int left, right;
if (isExternal(n)) {
return 1;
}
left = isRoman(n->left);
if (left == 0) {
return 0;
}
right = isRoman(n->right);
if ((right > 0) && (abs(left - right) <= 5)) {
return left + right + 1; // 부트리의 노드 수 반환
}
else
return 0;
}
int isExternal(NODE *n) {
return n->left == NULL && n->right == NULL;
}
void levelSearch(NODE *n) {
NODE *i;
int count = 1;
int internal_Count = 0;
int emperor_Count = 0;
enQueue(n);
while (1) {
i = deQueue();
if (i == NULL) break;
internal_Count++;
if (isEmperor(i)) { printf("%d\t황제노드\n", count); emperor_Count++; }
if (i->left != NULL && !isExternal(i->left)) enQueue(i->left);
if (i->right != NULL && !isExternal(i->right)) enQueue(i->right);
count++;
}
printf("방문한 내부 노드 수 %d개, 황제노드 수 %d개\n", internal_Count, emperor_Count);
}
// 이하 큐 관련 함수
void enQueue(NODE *n) {
if (isFull()) {
printf("Overflow.\n");
}
queue[rear] = n;
rear = (rear + 1) % MAX;
}
NODE* deQueue() {
int tmp = front;
if (isEmpty()) {
return NULL;
}
front = (front++) % MAX;
return queue[tmp];
}
int isEmpty() {
return front == rear;
}
int isFull() {
return ((rear + 1) % MAX) == front;
}
반응형
'C, C++ > 과제창고' 카테고리의 다른 글
| [C] 단일연결리스트 합병정렬 (singly linked list merge sort) (0) | 2018.10.14 |
|---|---|
| [C] YesOrNo 아키네이터 (0) | 2018.06.27 |