Your SlideShare is downloading. ×
  • Like
자료구조 Project4
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Now you can save presentations on your phone or tablet

Available for both IPhone and Android

Text the download link to your phone

Standard text messaging rates apply

자료구조 Project4

  • 137 views
Published

 

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
137
On SlideShare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
0
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. 과제수행일지 소속 조원 B2 조장 : 고충욱 자료조사 : 최완철,최수영 프로그래밍 : 강승우,최규준 과제수행기간 4일 I. 계획의 작성 연구제목 TREE 연구배경 트리에 대해 이해하고, 트리를 이용하여 상호참조 생성기를 만들 수 있다. 참고 C 로 배우는 쉬운 자료구조 이지영 출판사 한빛미디어 서적 참고자료 http://blog.naver.com/ctpoyou?Redirect=Log&logNo=104932778-트리의 참고 정의와 트리의 종류 URL http://internet512.chonbuk.ac.kr/datastructure/tree/tree8.htm-트리의 순회방법 II. 계획의 실행 첫째 날 2012 년 5 월 3 일 목요일오늘의 작업 조원의 업무 분담과 학습할 내용 및 과제에 대한 이해와 숙지
  • 2. 조장 : 고충욱 자료조사 : 강승우,최완철,최수영 프로그래밍 : 허규준토의 내용 위와 같이 조원의 업무 분담을 하였으며 과제를 위한 자료조사와 프로그래밍에 대한 내용을 인식하고 개별적으로 분담을 해서 조사를 하고 이해를 해 온 다음 그것을 조원들에게 설명해주는 것으로 방향을 잡았다.과제준비에 이번과제의 내용을 보니 자료조사가 많이 필요할 것 같아서 자료조사를 중점으로 서 해야겠다는 생각을 가지게 되었다. 느낀 점 둘째 날 2012 년 5 월 8 일 목요일오늘의 작업 학습할 내용에 대한 설명 및 이해 Tree(나무구조)의 정의 ⊙ 1 개 이상의 유한한 개수의 노드의 집합 ⊙ 루트 노드와 0 개 이상의 겹치지 않는 하위 나무 구조들의 집합으로 이루어짐 path : edge 에 의해 연결된 node 들의 집합 leaf(잎) : 자식이 없는 node(최하위 계층) forest :루트를 제외한 나머지 부분토의 내용 subtree : 큰 tree 에 속한 작은 tree node 의 degree : 하위 subtree 의 개수, 어느 특정노드의 자식 수 node 의 level : root node 부터 최하위 node 까지의 중첩되지 않은 path 의 node 개수 노드들의 자식 수 중에 가장 큰 자식 수 1) 노드 (Node) 노드는 트리를 구성하는 기본 요소를 말한다. 즉 아래의 그림에서 본다면 a 에서 g 까지의 각 요소
  • 3. 모두가 노드가 된다.2) 근(Root)트리의 가장 높은 레벨에 있는 노드를 루트 노드 또는 근 노드라 한다. 이 루트노드는 모든 노드의조상이 된다. 아래의 그림에서 a 노드는 루트 노드가 된다.3) 레벨(level)레벨은 각 노드가 근노드와 얼마만큼 떨어져 있는가를 알기 위해 상용한다. 예를들어 아래의그림에서 e 노드는 루트노드와 3 계층 떨어져 있으므로 level 은 3 이 된다.4) 부모 노드와 자식 노드parent node, child node 라 불린다. 서로 아래 위로 붙어 있는 노드로 상위의 노드가부모 노드가 된다. 하위의 노드는 자식노드가 되고 여러개의 자식노드는 하나의 부모노드만 가질 수 있다.아래의 그림에서 e 노드와 g 노드는 각각부모 노드 자식이 된다.5) 형제 노드sibling node 라 불린다. 같은 부모 노드를 갖는 자식 노드들은 형제들의 집합으로구성된다.
  • 4. 아래의 그림에서 b 노드와 c 노드는 sibling nod 가 된다.Binary Tree(이진 나무, 이진 트리)의 정의모든 내부 node 들이 둘 이하의 자식 node 를 갖는 나무, 노드가 하나도 없는공집합이거나root node 를 기준으로 왼쪽 이진나무, 오른쪽 이진나무로 이루어진 집합⊙ Complete Binary tree(완전 이진나무)가장 마지막 level 을 제외한 모든 node 들이 꽉 차있고 마지막 level 은 왼쪽 부터마지막node 까지 빈 칸이 없는 tree⊙ Full Binary Tree(포화 이진나무)마지막 level 까지 완전히 꽉 차있는 이진 트리를 말함이진 나무 순회(Tree Traverse)
  • 5. 위와 같은 트리가 있다고 한다면 각각 순회방법은 다음과 같습니다.⊙ 전위 순회(preorder traverse) : 뿌리(root)를 먼저 방문⊙ 중위 순회(inorder traverse) : 왼쪽 하위 트리를 방문 후 뿌리(root)를 방문⊙ 후위 순회(postorder traverse) : 하위 트리 모두 방문 후 뿌리(root)를 방문⊙ 층별 순회(level order traverse) : 위 쪽 node 들 부터 아래방향으로 차례로 방문전위 순회 : 0->1->3->7->8->4->9->10->2->5->11->6중위 순회 : 7->3->8->1->9->4->10->0->11->5->2->6후위 순회 : 7->8->3->9->10->4->1->11->5->6->2->0층별 순회 : 0->1->2->3->4->5->6->7->8->9->10->11★전위 순회는 뿌리->왼쪽 자식->오른쪽 자식 순★중위 순회는 왼쪽자식-> 뿌리-> 오른쪽 자식★후위 순회는 왼쪽자식->오른쪽 자식-> 뿌리★층별 순회는 그냥 노드의 순서대로
  • 6. 과제준비에 트리에 대한 개념은 어느 정도 이해 할 수 있었으나 이것을 사용하고 구현하기 서 위해서는 아직 많은 것이 부족한 것 같다. 더 많은 공부가 필요한 것 같다. 느낀 점 셋째 날 2012 년 5 월 10 일 목요일오늘의 작업 자료조사 내용 트리의 순회 이진 트리의 순회는 일정한 순서로 트리의 모든 노드들을 오직 한번씩만 방문하는 것이다. 트리의 순회는 트리 구조로 된 정보의 검색이나 수식 처리등에 유용하게 사용된다. 특정 노드에서 자신의 왼쪽 서브 트리를 모두 방문하고, 자기 노드를토의 내용 방문한 후에 오른쪽 서브 트리를 방문한다. 이 원리를 모든 노드에 재귀적으로 적용하면 모든 노드들을 한번씩 방문할 수 있다.
  • 7. 특정 노드에서 먼저 자기 노드를 방문하고, 왼쪽 서브 트리를 모두방문하고, 마지막으로 오른쪽 서브 트리를 모두 방문한다. 이 원리를모든 노드에 재귀적으로 적용하면 모든 노드를 한번씩 방문할 수있다.특정 노드에서 자신의 왼쪽 서브 트리와 오른쪽 서브 트리를 차례로방문한 후, 마지막으로 자신의 노드를 방문한다. 이 원리를 모든노드에 재귀적으로 적용하면 각 노드를 한번씩 방문할 수 있다.
  • 8. 과제준비에 순회에 대해 공부하면서 어떤걸 써야지 효과적일지에 대해 생각을 많이 하게 되었다. 서 그리고 순회를 구현하기 위해서 어떻게 할지 더 많은 회의가 필요할 것 같다. 느낀 점 넷째 날 2012 년 5 월 17 일 목요일오늘의 작업 소스파악 /************************************************************************ * cross_reference_generator.c * 단어의 빈도수 및 단어가 위치한 줄번호를 출력하는 프로그램 ************************************************************************/ #include <stdio.h> 초안 #include <stdlib.h> #include <string.h> #include <assert.h> typedef short bool; #define FALSE0 #define TRUE1
  • 9. typedef struct _WORDNODE *PWORDNODE;typedef struct _LINENODE *PLINENODE;typedef struct _LINENODE// 단어가 출현시 그 라인번호에 대한 구조체.{intline_number;// 라인번호.PLINENODEnext_node;// 다음 노드} LINENODE;typedef struct _WORDNODE//Binary Search Tree 의 노드 구조체.{charword[32];// 단어.intfrequency;// 빈도수PLINENODEpLine_node;// 단어가 나오는 라인번호 (Linked List 로 구현)PWORDNODEleft_child;// 왼쪽자식노드PWORDNODEright_child;// 오른쪽자식노드} WORDNODE;/************************************************************************* Function Prototype Declare************************************************************************/// 노드를 삽입void InsertNode( PWORDNODE* pRoot, char* aKey, int aLineNumber );/* 같은 단어가 존재시에는 해당 노드 반환 혹은*존재 하지 않을 시 삽입 할 위치의 parent node 의 포인터 반환 */PWORDNODE Search( PWORDNODE pRoot , char* key ,bool* exist_same);/* 사전 순서대로 단어, 빈도수, 그리고 총 단어수 출력*(inorder-traversal)*/void PrintTree( PWORDNODE pRoot );int main( int argc , char* argv[] ){PWORDNODEpRoot= NULL ;// 트리의 루트
  • 10. charstring[256] = {0};// 텍스트파일 한 라인의 버퍼char*ptr_key;// 토큰된 단어에 대한 포인터char*ptr_lwr_key;// lower key , 소문자로 변환된 단어의 포인터intline_number = 0 ;// 해당 라인 번호FILE*in_file;// 읽어들일 파일 구조체.if ( argc != 2 || strlen(argv[1]) == 0) {printf("Usage : %s filenamen" , argv[0]);return 0;}in_file = fopen(argv[1],"r");// 파일을 읽기전용 모드로 연다.if (!in_file) {fprintf(stderr,"Can not open a file. : %s n",argv[1]);exit(1);}while ( !feof(in_file) ) // in_file 이 끝에 도달 할 때까지 아래 내용을 실행.{memset(string,0,sizeof(string));// 한 라인에 대한 버퍼를 초기화.fgets( string , sizeof(string),in_file);// 파일로 부터 라인을 읽어옴++line_number;//라인번호 증가./*************************************************************************strtok , strlwr 사용법은 Creference manual 참조 바람.************************************************************************/// 문자열에서 separator 로 단어들을 추출ptr_key = strtok( string, " `~!@#$%^&*()_-=+[]{};:"|/?,.<>tn" );while( ptr_key != NULL ){ptr_lwr_key = strlwr(ptr_key); // 해당 단어를 소문자로 변환// 해당단어와 라인번호를 binary search 트리에 삽입InsertNode( &pRoot , ptr_lwr_key , line_number );
  • 11. // 다음 단어 추출.ptr_key = strtok( NULL, " `~!@#$%^&*()_-=+[]{};:"|/?,.<>tn" );}}if ( pRoot )// 트리에 노드가 존재 한다면.{printf("--------------------------------------------------------------------n");printf("%-19s|%-11s|%-19sn", " 단어" , " 빈도수"," 라인");printf("--------------------------------------------------------------------n");PrintTree( pRoot );// 트리 내용 출력.printf("--------------------------------------------------------------------n");}fclose(in_file);// 파일을 닫음.return 0;}/************************************************************************* 사전 순서대로 단어, 빈도수, 그리고 총 단어수 출력 (inorder-traversal)************************************************************************/void PrintTree( PWORDNODE pRoot ){PLINENODE tmpLineNode;// 해당 단어의 라인번호를 출력하기 위한 임시 포인터if ( pRoot )// 루트가 널이 아니라면{tmpLineNode = pRoot->pLine_node ;// tmpLineNode 는 라인노드를 가르킴PrintTree( pRoot->left_child );// 왼쪽 자식노드 출력.// 중간, 즉 루트 노드 출력.// 해당 노드의 단어와 빈도수 출력printf(" %-18s|%9d |", pRoot->word , pRoot->frequency );while ( tmpLineNode ) {// tmpLineNode 가 널일때 까지.
  • 12. // 라인번호 출력printf("%4d",tmpLineNode->line_number);// 임시포인터는 링키드리스트의 다음 노드를 가리키게 함tmpLineNode = tmpLineNode->next_node;}printf("n");PrintTree( pRoot->right_child );// 오른쪽 자식노드 출력}}/*************************************************************************같은 단어가 존재시에는 해당 노드 반환 혹은*존재 하지 않을 시삽입 할 위치의 parent node 의 포인터 반환************************************************************************/PWORDNODE Search( PWORDNODE pRoot , char* key ,bool* exist_same){PWORDNODE preNode = pRoot;// parent 노드를 기억 할 임시 변수while ( pRoot )// 해당노드가 널일때 까지.{preNode = pRoot;// 해당노드를 기억.if ( strcmp( key, pRoot->word ) == 0 )// 해당노드가 같은 단어의 노드일경우{*exist_same = TRUE;// 같은것이 있다는것을 true 로 표시return pRoot;// 그 노드를 반환.}if ( strcmp( key, pRoot->word ) < 0)// 키가 해당노드의 단어보다 앞쪽이라면pRoot = pRoot->left_child;// 왼쪽 자식노드로 이동.elsepRoot = pRoot->right_child;// 뒤쪽의 단어라면 오른쪽 자식노드로 이동}
  • 13. // 널이라면 그 전 노드(parent 노드)를 반환return preNode;}/************************************************************************* Tree 에 노드를 삽입. Binary Search Tree 로 구성.************************************************************************/void InsertNode( PWORDNODE* pRoot, char* aKey, int aLineNumber ){boolexist_same_word = FALSE;// 같은 단어가 트리내에 존재할시 true// 같은 단어가 트리 내에 존재 하면 그 단어에 대한 노드,// 없을 시에 새로 삽입될 위치의 parent 노드PWORDNODE tmpWordNode = Search( *pRoot , aKey ,&exist_same_word);PWORDNODE insertWordNode = NULL;// 트리에 삽입 될 노드PLINENODE ptrLineNode = NULL; // 줄번호를 저장 할 노드./*************************************************************key 가 tree 내에 존재할시.************************************************************/if ( exist_same_word ){// 반환된 노드 즉, tmpWordNode 는 Key 에 대한 노드// 노드 내의 빈도수 증가++(tmpWordNode->frequency);// 라인번호에 대한 링키드 리스트의 끝 부분으로 이동.ptrLineNode = tmpWordNode->pLine_node;while( ptrLineNode->next_node )ptrLineNode = ptrLineNode->next_node;// 새로운 라인노드를 붙여준다.ptrLineNode->next_node = (PLINENODE)malloc(sizeof(LINENODE));ptrLineNode->next_node->line_number = aLineNumber ; // 라인번호 저장
  • 14. ptrLineNode->next_node->next_node = NULL;// 다음노드는 NULL 로 처리.}else if ( tmpWordNode || !(*pRoot) ){/************************************************************* key 가 트리내에 없음.************************************************************///////////////////////////////////////////////////////////////////////////// 새로운 노드 생성, 라인번호와 단어를 저장.insertWordNode = (PWORDNODE)malloc(sizeof(WORDNODE));if (!insertWordNode) {fprintf(stderr,"The Memory is fulln");exit(1);}memset( insertWordNode , 0 , sizeof(WORDNODE));// 초기화strcpy( insertWordNode->word , aKey );// 삽입될 노드에 키 복사++(insertWordNode->frequency);// 빈도수 증가.// 새로운 라인노드를 붙여준다.insertWordNode->pLine_node = (PLINENODE)malloc(sizeof(LINENODE));// 해당단어가 출현한 라인번호 저장.insertWordNode->pLine_node->line_number = aLineNumber ;// 다음노드는 NULL 로 처리.insertWordNode->pLine_node->next_node = NULL;//////////////////////////////////////////////////////////////////////////// 그 노드를 적절한 위치에 삽입if (*pRoot) // 루트가 널이 아니라면{ // 키가 해당노드의 단어보다 앞쪽이라면if ( strcmp( aKey, tmpWordNode->word ) < 0)tmpWordNode->left_child = insertWordNode;// 왼쪽 자식노드에 삽입.
  • 15. else tmpWordNode->right_child = insertWordNode; // 아니라면 오른쪽 노드에 삽입. } else// 루트가 널이라면 루트에 해당 노드를 저장. *pRoot = insertWordNode; } } // cross_reference_generator.c END 단어 빈도수를 찾는 프로그램의 알고리즘은 먼저 단어를 저장할 문자열배열(data), 빈도수를 나타내는(data), 단어가 등장한 라인을 나타내는 (data), 다음 노드(구조체)를 가르키는 두 개의 포인터(왼쪽,오른쪽 자식)으로 구성되있는 구조체를 사용 하여 이진트리를 구성하며 프로그램이 진행된다. 먼저 파일의 한 라인을 읽어와서 “`~!@#$%^&*()_-=+[]{};:"|/?,.<>tn” 앞의 문자로 끊어 한 단어로 인식 하고 라인 별로 읽기 때문에 다음 라인으로 갈 때 마다 라인넘버를 1 씩 증가 시켜 data 로 사용 하게 된다.알고리즘 한 단어가 트리에 이미 저장되어 있는지 중복 검사 후 중복 되는 단어가 있다면 해석 해당 단어가 저장 되있는 구조체에서 빈도수만 증가 시키고, 중복되지 않는다면(처음 등장하는 단어) 새로운 구조체를 만들어 저장 하고 빈도수, 등장하는 라인도 추가 시킨다. 단어를 추가시키는 방법은 접근한 구조체의 단어보다 앞의 단어이면 왼쪽, 뒤의 단어이면 오른쪽으로 저장한다. 파일의 모든 문자들을 읽은 후 트리의 저장이 완료 되면, 중위 순회 방법으로 트리의 단어,빈도수,라인넘버를 출력 한다 중위 순회는 출력의 우선순위가 왼쪽 노드의
  • 16. 값>현재 노드의 값>오른쪽 노드의 값 으로 정해져 있고 이 순서대로 단어를 출력 하면 해당 노드보다 앞의 단어는 왼쪽으로 게속 저장했으므로 이 방법을 사용 하여 사전식순으로 단어를 출력 한다. 출력은 다음 노드의 값이 없을때 까지 반복 하고 프로그램을 종료합니다. Ⅳ. 반성과제를 과제를 마무리하지 못해 알고리즘을 해석하면서 과제를 마무리하였다.마치면서 많은 아쉬움을 가진 프로젝트가 되었다.느낀 점