CHAP 7 1 n n typedef struct Tree

  • Slides: 66
Download presentation
CHAP 7: 트리 1

CHAP 7: 트리 1

링크의 구현 노드는 구조체로 표현 n 링크는 포인터로 표현 n typedef struct Tree. Node

링크의 구현 노드는 구조체로 표현 n 링크는 포인터로 표현 n typedef struct Tree. Node { int data; struct Tree. Node *left, *right; } Tree. Node; 20

링크 표현법 프로그램 #include <stdio. h> #include <stdlib. h> #include <memory. h> typedef struct

링크 표현법 프로그램 #include <stdio. h> #include <stdlib. h> #include <memory. h> typedef struct Tree. Node { int data; struct Tree. Node *left, *right; } Tree. Node; // n 1 // / | // n 2 n 3 void main() { Tree. Node *n 1, *n 2, *n 3; n 1= (Tree. Node *)malloc(sizeof(Tree. Node)); n 2= (Tree. Node *)malloc(sizeof(Tree. Node)); n 3= (Tree. Node *)malloc(sizeof(Tree. Node)); 21

전위순회 프로그램 n 순환 호출을 이용한다. preorder(x) if x≠NULL then print DATA(x); preorder(LEFT(x)); preorder(RIGHT(x));

전위순회 프로그램 n 순환 호출을 이용한다. preorder(x) if x≠NULL then print DATA(x); preorder(LEFT(x)); preorder(RIGHT(x)); 25

중위순회 알고리즘 n 순환 호출을 이용한다. inorder(x) if x≠NULL then inorder(LEFT(x)); print DATA(x); inorder(RIGHT(x));

중위순회 알고리즘 n 순환 호출을 이용한다. inorder(x) if x≠NULL then inorder(LEFT(x)); print DATA(x); inorder(RIGHT(x)); 28

후위순회 알고리즘 n 순환 호출을 이용한다. postorder(x) if x≠NULL then postorder(LEFT(x)); postorder(RIGHT(x)); print DATA(x);

후위순회 알고리즘 n 순환 호출을 이용한다. postorder(x) if x≠NULL then postorder(LEFT(x)); postorder(RIGHT(x)); print DATA(x); 31

순회 프로그램 typedef struct Tree. Node { int data; struct Tree. Node *left, *right;

순회 프로그램 typedef struct Tree. Node { int data; struct Tree. Node *left, *right; } Tree. Node; // 15 // 4 20 // 1 16 25 Tree. Node n 1 = {1, NULL}; Tree. Node n 2 = {4, &n 1, NULL}; Tree. Node n 3 = {16, NULL}; Tree. Node n 4 = {25, NULL}; Tree. Node n 5 = {20, &n 3, &n 4}; Tree. Node n 6 = {15, &n 2, &n 5}; Tree. Node *root = &n 6; 33

// 중위 순회 inorder( Tree. Node *root ){ if ( root ){ inorder( root->left

// 중위 순회 inorder( Tree. Node *root ){ if ( root ){ inorder( root->left ); printf("%d", root->data ); inorder( root->right ); } } // 전위 순회 preorder( Tree. Node *root ){ if ( root ){ printf("%d", root->data ); preorder( root->left ); preorder( root->right ); } } // 왼쪽서브트리 순회 // 노드 방문 // 오른쪽서브트리 순회 // 노드 방문 // 왼쪽서브트리 순회 // 오른쪽서브트리 순회 34

// 후위 순회 postorder( Tree. Node *root ){ if ( root ){ postorder( root->left

// 후위 순회 postorder( Tree. Node *root ){ if ( root ){ postorder( root->left ); postorder( root->right ); printf("%d", root->data ); } } // 왼쪽서브트리 순회 // 오른쪽서브트리순회 // 노드 방문 void main() { inorder(root); preorder(root); postorder(root); } 35

레벨 순회 알고리즘 n 1. 2. 3. 4. 5. 6. 7. 8. level_order(root) initialize

레벨 순회 알고리즘 n 1. 2. 3. 4. 5. 6. 7. 8. level_order(root) initialize queue; enqueue(queue, root); while is_empty(queue)≠TRUE do x← dequeue(queue); if( x≠NULL) then print DATA(x); enqueue(queue, LEFT(x)); enqueue(queue, RIGHT(x)); 37

수식트리 알고리즘 evaluate(exp) 1. 2. 3. 4. 5. 6. if exp = NULL then

수식트리 알고리즘 evaluate(exp) 1. 2. 3. 4. 5. 6. if exp = NULL then return 0; else x←evaluate(exp->left); y←evaluate(exp->right); op←exp->data; return (x op y); 40

프로그램 typedef struct Tree. Node { int data; struct Tree. Node *left, *right; }

프로그램 typedef struct Tree. Node { int data; struct Tree. Node *left, *right; } Tree. Node; // + // * + // 1 4 16 25 Tree. Node n 1={1, NULL}; Tree. Node n 2={4, NULL}; Tree. Node n 3={'*', &n 1, &n 2}; Tree. Node n 4={16, NULL}; Tree. Node n 5={25, NULL}; Tree. Node n 6={'+', &n 4, &n 5}; Tree. Node n 7={'+', &n 3, &n 6}; Tree. Node *exp= &n 7; 41

int evaluate(Tree. Node *root) { if( root == NULL) return 0; if( root->left ==

int evaluate(Tree. Node *root) { if( root == NULL) return 0; if( root->left == NULL && root->right == NULL) return root->data; else { int op 1 = evaluate(root->left); int op 2 = evaluate(root->right); switch(root->data){ case '+': return op 1+op 2; case '-': return op 1 -op 2; case '*': return op 1*op 2; case '/': return op 1/op 2; } } return 0; } void main() { printf("%d", evaluate(exp)); } 42

디렉토리 용량 계산 프로그램 int calc_direc_size(Tree. Node *root) { int left_dir, right_dir; if (

디렉토리 용량 계산 프로그램 int calc_direc_size(Tree. Node *root) { int left_dir, right_dir; if ( root ){ left_size = calc_direc_size( root->left ); right_size = calc_direc_size(root->right ); return (root->data+left_size+right_size); } } void main() { Tree. Node n 4={500, NULL}; Tree. Node n 5={200, NULL}; Tree. Node n 3={100, &n 4, &n 5}; Tree. Node n 2={50, NULL}; Tree. Node n 1={0, &n 2, &n 3}; printf("디렉토리의 크기=%dn", calc_direc_size(&n 1)); } 44

이진트리연산: 노드 개수 탐색 트리안의 노드의 개 수를 계산 n 각각의 서브트리에 대하 여

이진트리연산: 노드 개수 탐색 트리안의 노드의 개 수를 계산 n 각각의 서브트리에 대하 여 순환 호출한 다음, 반환되는 값에 1을 더하 여 반환 n int get_node_count(Tree. Node *node) { int count=0; if( node != NULL ) count = 1 + get_node_count(node->left)+ get_node_count(node->right); return count; } 6 3 1 2 1 1 45

이진트리연산: 높이 n 서브트리에 대하여 순환 호출하고 서브 트리들의 반환값 중에서 최대값을 구하여 반환

이진트리연산: 높이 n 서브트리에 대하여 순환 호출하고 서브 트리들의 반환값 중에서 최대값을 구하여 반환 h = 1+ max(hleft, hright) int get_height(Tree. Node *node) { int height = 0; if(node == NULL) return height; if(node->left != NULL || node->right != NULL) height = 1 + max(get_height(node->left), get_height(node->right)); return height; } 46

이진탐색트리에서의 탐색연산 search(x, k) if x = NULL then return NULL; if k =

이진탐색트리에서의 탐색연산 search(x, k) if x = NULL then return NULL; if k = x->key then return x; else if k < x->key then return search(x->left, k); else return search(x->right, k); 53

순환적인 방법 //순환적인 탐색 함수 Tree. Node *search(Tree. Node *node, int key) { if

순환적인 방법 //순환적인 탐색 함수 Tree. Node *search(Tree. Node *node, int key) { if ( node == NULL ) return NULL; if ( key == node->key ) return node; else if ( key < node->key ) return search(node->left, key); else return search(node->right, key); } 55

반복적인 방법 // 반복적인 탐색 함수 Tree. Node *search(Tree. Node *node, int key) {

반복적인 방법 // 반복적인 탐색 함수 Tree. Node *search(Tree. Node *node, int key) { while(node != NULL){ if( key == node->key ) return node; else if( key < node->key ) node = node->left; else node = node->right; } return NULL; // 탐색에 실패했을 경우 NULL 반환 } 56

이진탐색트리에서의 삽입연산 insert_node(T, z) p←NULL; t←root; while t≠NULL do p←t; if z->key < p->key

이진탐색트리에서의 삽입연산 insert_node(T, z) p←NULL; t←root; while t≠NULL do p←t; if z->key < p->key then t←p->left; else t←p->right; if p = NULL then root←z; else if z->key < p->key then p->left←z else p->right←z // 트리가 비어있음 58

이진탐색트리에서의 삽입연산 // key가 트리 안에 없으므로 삽입 가능 n = (Tree. Node *)

이진탐색트리에서의 삽입연산 // key가 트리 안에 없으므로 삽입 가능 n = (Tree. Node *) malloc(sizeof(Tree. Node)); if( n == NULL ) return; // 데이터 복사 n->key = key; n->left = n->right = NULL; // 부모 노드와 링크 연결 if( p != NULL ) if( key < p->key ) p->left = n; else p->right = n; else *root = n; } 60