SlideShare ist ein Scribd-Unternehmen logo
1 von 12
Downloaden Sie, um offline zu lesen
B2조 자료구조
       보고서
[Project #4 : 상호참조 생성기]




                    조장 : 고충욱
                    조원 : 강승우
                          허규준
                          최완철
                          최수영
과제수행일지
  소속                                       조원

  B2             조장 : 고충욱         자료조사 : 최완철,최수영          프로그래밍 : 강승우,최규준

과제수행기간                                      4일

                               I. 계획의 작성

 연구제목     TREE




 연구배경     트리에 대해 이해하고, 트리를 이용하여 상호참조 생성기를 만들 수 있다.




          참고 서적      C로 배우는 쉬운 자료구조 이지영 출판사 한빛미디어



 참고자료


                     http://blog.naver.com/ctpoyou?Redirect=Log&logNo=10493277
                     8-트리의 정의와 트리의 종류
          참고 URL
                     http://internet512.chonbuk.ac.kr/datastructure/tree/tree8.ht
                     m-트리의 순회방법


                              II. 계획의 실행

 첫째 날                              2012년 5월 3일 목요일

오늘의 작업              조원의 업무 분담과 학습할 내용 및 과제에 대한 이해와 숙지

         조장 : 고충욱
         자료조사 : 강승우,최완철,최수영
         프로그래밍 : 허규준
토의 내용
         위와 같이 조원의 업무 분담을 하였으며 과제를 위한 자료조사와 프로그래밍에 대한 내
         용을 인식하고 개별적으로 분담을 해서 조사를 하고 이해를 해 온 다음 그것을 조원들
         에게 설명해주는 것으로 방향을 잡았다.


과제준비에서   이번과제의 내용을 보니 자료조사가 많이 필요할 것 같아서 자료조사를 중점으로 해야
 느낀 점    겠다는 생각을 가지게 되었다.
둘째 날                            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까지
         의 각 요소
         모두가 노드가 된다.
         2) 근(Root)
         트리의 가장 높은 레벨에 있는 노드를           루트 노드 또는 근 노드라 한다. 이 루트 노드
         는 모든 노드의
         조상이 된다. 아래의 그림에서 a 노드는 루트 노드가 된다.
         3) 레벨(level)
         레벨은 각 노드가 근노드와 얼마만큼 떨어져 있는가를 알기 위해 상용한다. 예를 들어
토의 내용    아래의
         그림에서 e 노드는 루트노드와 3계층 떨어져 있으므로 level은 3이 된다.
         4) 부모 노드와 자식 노드
         parent node, child node라 불린다. 서로 아래 위로 붙어 있는 노드로 상위의 노드가
         부모 노드가 된다. 하위의 노드는 자식노드가 되고 여러개의 자식노드는 하나의 부모
         노드만 가질 수 있다.
         아래의 그림에서 e 노드와 g노드는 각각부모 노드 자식이 된다.
         5) 형제 노드
         sibling node라 불린다. 같은 부모 노드를 갖는 자식 노드들은 형제들의 집합으로 구성
         된다.
         아래의 그림에서 b노드와 c노드는 sibling nod가 된다.


         Binary Tree(이진 나무, 이진 트리)의 정의
         모든 내부 node들이 둘 이하의 자식node를 갖는 나무, 노드가 하나도 없는 공집합 이
         거나
         root node를 기준으로 왼쪽 이진나무, 오른쪽 이진나무로 이루어진 집합


         ⊙ Complete Binary tree(완전 이진나무)
         가장 마지막 level을 제외한 모든 node들이 꽉 차있고 마지막 level은 왼쪽 부터 마지
         막
         node까지 빈 칸이 없는 tree
⊙ Full Binary Tree(포화 이진나무)
마지막 level까지 완전히 꽉 차있는 이진 트리를 말함
이진 나무 순회(Tree Traverse)




위와 같은 트리가 있다고 한다면 각각 순회방법은 다음과 같습니다.
⊙ 전위 순회(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
★전위 순회는 뿌리->왼쪽 자식->오른쪽 자식 순
★중위 순회는 왼쪽자식-> 뿌리-> 오른쪽 자식
         ★후위 순회는 왼쪽자식->오른쪽 자식-> 뿌리
         ★층별 순회는 그냥 노드의 순서대로




과제준비에서   트리에 대한 개념은 어느 정도 이해 할 수 있었으나 이것을 사용하고 구현하기 위해서
 느낀 점    는 아직 많은 것이 부족한 것 같다. 더 많은 공부가 필요한 것 같다.




 셋째 날                     2012년 5월 10일 목요일
오늘의 작업                         자료조사 내용
         트리의 순회
         이진 트리의 순회는 일정한 순서로 트리의 모든 노드들을 오직 한번씩만 방문하는 것이
         다. 트리의 순회는 트리 구조로 된 정보의 검색이나 수식 처리등에 유용하게 사용된다.




             특정 노드에서 자신의 왼쪽 서브 트리를 모두 방문하고, 자기 노드를
             방문한 후에 오른쪽 서브 트리를 방문한다. 이 원리를 모든 노드에 재
             귀적으로 적용하면 모든 노드들을 한번씩 방문할 수 있다.




토의 내용




            특정 노드에서 먼저 자기 노드를 방문하고, 왼쪽 서브 트리를 모두
방문하고, 마지막으로 오른쪽 서브 트리를 모두 방문한다. 이 원리를
            모든 노드에 재귀적으로 적용하면 모든 노드를 한번씩 방문할 수 있
            다.




             특정 노드에서 자신의 왼쪽 서브 트리와 오른쪽 서브 트리를 차례로
             방문한 후, 마지막으로 자신의 노드를 방문한다. 이 원리를 모든 노드
             에 재귀적으로 적용하면 각 노드를 한번씩 방문할 수 있다.




과제준비에서   순회에 대해 공부하면서 어떤걸 써야지 효과적일지에 대해 생각을 많이 하게 되었다.
 느낀 점    그리고 순회를 구현하기 위해서 어떻게 할지 더 많은 회의가 필요할 것 같다.
넷째 날                                    2012년 5월 17일 목요일
오늘의 작업                                            소스파악
         /************************************************************************
         *                          cross_reference_generator.c
         *          단어의 빈도수 및 단어가 위치한 줄번호를 출력하는 프로그램
         ************************************************************************/

         #include <stdio.h>
         #include <stdlib.h>
         #include <string.h>
         #include <assert.h>

         typedef short bool;

         #define FALSE    0
         #define TRUE     1

         typedef struct _WORDNODE *PWORDNODE;
         typedef struct _LINENODE *PLINENODE;

         typedef struct _LINENODE           // 단어가 출현시 그 라인번호에 대한 구조체.
         {
                 int                      line_number;        // 라인번호.
                 PLINENODE         next_node;                 // 다음 노드


 초안      } LINENODE;

         typedef struct _WORDNODE                    //       Binary Search Tree의 노드 구조체.
         {
                char           word[32];                      // 단어.
                int                       frequency;                // 빈도수
                PLINENODE          pLine_node;                // 단어가 나오는 라인번호 (Linked
         List로 구현)
                 PWORDNODE         left_child;             // 왼쪽자식노드
                 PWORDNODE         right_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[] )
{

        PWORDNODE           pRoot   = NULL ;         // 트리의 루트
        char     string[256] = {0};                  // 텍스트파일 한 라인의 버퍼
        char*    ptr_key;                                    // 토큰된 단어에 대한 포인터
        char*    ptr_lwr_key;                        // lower key , 소문자로 변환된 단어
의 포인터
     int                    line_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 사용법은 C reference 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 );
                           // 다음 단어 추출.
                           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가 널일때 까지.
                         // 라인번호 출력
                           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;                        // 왼쪽 자
식노드로 이동.
                 else
                          pRoot = pRoot->right_child;                  // 뒤쪽의 단어라면
오른쪽 자식노드로 이동
     }
     // 널이라면 그 전 노드(parent 노드)를 반환
        return preNode;
}

/************************************************************************
*                          Tree에 노드를 삽입. Binary Search Tree로 구성.
************************************************************************/
void InsertNode( PWORDNODE* pRoot, char* aKey, int aLineNumber )
{
        bool   exist_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 ; // 라인번
호 저장
           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;                            //
           왼쪽 자식노드에 삽입.
                                     else
                                                 tmpWordNode->right_child                    =    insertWordNode;
           // 아니라면 오른쪽 노드에 삽입.
                      }
                      else  // 루트가 널이라면 루트에 해당 노드를 저장.
                                     *pRoot = insertWordNode;
                  }
           }
           // cross_reference_generator.c END
           단어 빈도수를 찾는 프로그램의 알고리즘은 먼저 단어를 저장할 문자열배열(data), 빈
           도수를 나타내는(data), 단어가 등장한 라인을 나타내는 (data), 다음 노드(구조체)를
           가르키는 두 개의 포인터(왼쪽,오른쪽 자식)으로 구성되있는 구조체를 사용 하여 이진트
           리를 구성하며 프로그램이 진행된다.
           먼저 파일의 한 라인을 읽어와서 “`~!@#$%^&*()_-=+[]{};:'"|/?,.<>tn” 앞
           의 문자로 끊어 한 단어로 인식 하고 라인 별로 읽기 때문에 다음 라인으로 갈 때 마다
           라인넘버를 1씩 증가 시켜 data로 사용 하게 된다.
           한 단어가 트리에 이미 저장되어 있는지 중복 검사 후 중복 되는 단어가 있다면 해당
           단어가 저장 되있는 구조체에서 빈도수만 증가 시키고, 중복되지 않는다면(처음 등장하
알고리즘 해석
           는 단어) 새로운 구조체를 만들어 저장 하고 빈도수, 등장하는 라인도 추가 시킨다.
           단어를 추가시키는 방법은 접근한 구조체의 단어보다 앞의 단어이면 왼쪽, 뒤의 단어이
           면 오른쪽으로 저장한다.
           파일의 모든 문자들을 읽은 후 트리의 저장이 완료 되면, 중위 순회 방법으로 트리의
           단어,빈도수,라인넘버를 출력 한다 중위 순회는 출력의 우선순위가 왼쪽 노드의 값>현
           재 노드의 값>오른쪽 노드의 값 으로 정해져 있고 이 순서대로 단어를 출력 하면 해당
           노드보다 앞의 단어는 왼쪽으로 게속 저장했으므로 이 방법을 사용 하여 사전식순으로
           단어를 출력 한다.
           출력은 다음 노드의 값이 없을때 까지 반복 하고 프로그램을 종료합니다.
                                           Ⅳ. 반성



과제를 마치면서   과제를 마무리하지 못해 알고리즘을 해석하면서 과제를 마무리하였다.
  느낀 점     많은 아쉬움을 가진 프로젝트가 되었다.

Weitere ähnliche Inhalte

Was ist angesagt?

4. 함수포인터
4. 함수포인터4. 함수포인터
4. 함수포인터Hoyoung Jung
 
포인터의기초 (2) - 포인터 사용하기1
포인터의기초 (2) - 포인터 사용하기1포인터의기초 (2) - 포인터 사용하기1
포인터의기초 (2) - 포인터 사용하기1Hoyoung Jung
 
Smart pointer
Smart pointerSmart pointer
Smart pointerpknhacker
 
포인터의 기초(1)
포인터의 기초(1)포인터의 기초(1)
포인터의 기초(1)Hoyoung Jung
 
자료구조 Project3
자료구조 Project3자료구조 Project3
자료구조 Project3KoChungWook
 
자료구조 06 최종 보고서
자료구조 06 최종 보고서자료구조 06 최종 보고서
자료구조 06 최종 보고서pkok15
 
이산치수학 Project7
이산치수학 Project7이산치수학 Project7
이산치수학 Project7KoChungWook
 
Searching algorithm(nanheekim)
Searching algorithm(nanheekim)Searching algorithm(nanheekim)
Searching algorithm(nanheekim)Nanhee Kim
 
파이썬정리 20160130
파이썬정리 20160130파이썬정리 20160130
파이썬정리 20160130Yong Joon Moon
 
파이썬 크롤링 모듈
파이썬 크롤링 모듈파이썬 크롤링 모듈
파이썬 크롤링 모듈Yong Joon Moon
 
안드로이드기초
안드로이드기초안드로이드기초
안드로이드기초hylo926
 
주니어 개발자도 이해 할 수 있는 Go - Scope 편
주니어 개발자도 이해 할 수 있는 Go - Scope 편주니어 개발자도 이해 할 수 있는 Go - Scope 편
주니어 개발자도 이해 할 수 있는 Go - Scope 편Darion Kim
 
파이썬 xml 이해하기
파이썬 xml 이해하기파이썬 xml 이해하기
파이썬 xml 이해하기Yong Joon Moon
 
Reflect package 사용하기
Reflect package 사용하기Reflect package 사용하기
Reflect package 사용하기Yong Joon Moon
 
파이썬 Xml 이해하기
파이썬 Xml 이해하기파이썬 Xml 이해하기
파이썬 Xml 이해하기Yong Joon Moon
 

Was ist angesagt? (19)

4. 함수포인터
4. 함수포인터4. 함수포인터
4. 함수포인터
 
3.포인터
3.포인터3.포인터
3.포인터
 
포인터의기초 (2) - 포인터 사용하기1
포인터의기초 (2) - 포인터 사용하기1포인터의기초 (2) - 포인터 사용하기1
포인터의기초 (2) - 포인터 사용하기1
 
Smart pointer
Smart pointerSmart pointer
Smart pointer
 
Cp2 w5
Cp2 w5Cp2 w5
Cp2 w5
 
포인터의 기초(1)
포인터의 기초(1)포인터의 기초(1)
포인터의 기초(1)
 
자료구조 Project3
자료구조 Project3자료구조 Project3
자료구조 Project3
 
자료구조 06 최종 보고서
자료구조 06 최종 보고서자료구조 06 최종 보고서
자료구조 06 최종 보고서
 
이산치수학 Project7
이산치수학 Project7이산치수학 Project7
이산치수학 Project7
 
Searching algorithm(nanheekim)
Searching algorithm(nanheekim)Searching algorithm(nanheekim)
Searching algorithm(nanheekim)
 
파이썬정리 20160130
파이썬정리 20160130파이썬정리 20160130
파이썬정리 20160130
 
파이썬 크롤링 모듈
파이썬 크롤링 모듈파이썬 크롤링 모듈
파이썬 크롤링 모듈
 
안드로이드기초
안드로이드기초안드로이드기초
안드로이드기초
 
주니어 개발자도 이해 할 수 있는 Go - Scope 편
주니어 개발자도 이해 할 수 있는 Go - Scope 편주니어 개발자도 이해 할 수 있는 Go - Scope 편
주니어 개발자도 이해 할 수 있는 Go - Scope 편
 
Light Tutorial Python
Light Tutorial PythonLight Tutorial Python
Light Tutorial Python
 
파이썬 xml 이해하기
파이썬 xml 이해하기파이썬 xml 이해하기
파이썬 xml 이해하기
 
파이썬 심화
파이썬 심화파이썬 심화
파이썬 심화
 
Reflect package 사용하기
Reflect package 사용하기Reflect package 사용하기
Reflect package 사용하기
 
파이썬 Xml 이해하기
파이썬 Xml 이해하기파이썬 Xml 이해하기
파이썬 Xml 이해하기
 

Andere mochten auch

Andere mochten auch (20)

자료구조02
자료구조02자료구조02
자료구조02
 
6비트덧셈기
6비트덧셈기6비트덧셈기
6비트덧셈기
 
자료구조01
자료구조01자료구조01
자료구조01
 
자료구조06
자료구조06자료구조06
자료구조06
 
5통신망에서 길 찾기
5통신망에서 길 찾기5통신망에서 길 찾기
5통신망에서 길 찾기
 
7그룹 코드
7그룹 코드7그룹 코드
7그룹 코드
 
3콤비네이션
3콤비네이션3콤비네이션
3콤비네이션
 
자료구조05
자료구조05자료구조05
자료구조05
 
Mst 구하기
Mst 구하기Mst 구하기
Mst 구하기
 
Pa1 6 p-dagang_periodik
Pa1 6 p-dagang_periodikPa1 6 p-dagang_periodik
Pa1 6 p-dagang_periodik
 
2데이터베이스 시스템
2데이터베이스 시스템2데이터베이스 시스템
2데이터베이스 시스템
 
Pa1 5 siklus-jasa
Pa1 5 siklus-jasaPa1 5 siklus-jasa
Pa1 5 siklus-jasa
 
Akuntansi keuangan kewajiban jangka pendek
Akuntansi keuangan kewajiban jangka pendekAkuntansi keuangan kewajiban jangka pendek
Akuntansi keuangan kewajiban jangka pendek
 
Pa1 6 p-dagang_periodik
Pa1 6 p-dagang_periodikPa1 6 p-dagang_periodik
Pa1 6 p-dagang_periodik
 
Tema 1
Tema 1Tema 1
Tema 1
 
TAOCP1 - 1.2.11.1 - O 표기법
TAOCP1 - 1.2.11.1 - O 표기법TAOCP1 - 1.2.11.1 - O 표기법
TAOCP1 - 1.2.11.1 - O 표기법
 
Special journal hyper
Special journal hyperSpecial journal hyper
Special journal hyper
 
Pengantar akuntansi 1
Pengantar akuntansi 1Pengantar akuntansi 1
Pengantar akuntansi 1
 
Pengantar akuntansi 1
Pengantar akuntansi 1Pengantar akuntansi 1
Pengantar akuntansi 1
 
빅데이터
빅데이터빅데이터
빅데이터
 

Ähnlich wie 자료구조04

자료구조 트리 보고서
자료구조 트리 보고서자료구조 트리 보고서
자료구조 트리 보고서mil23
 
자료구조 04 최종 보고서
자료구조 04 최종 보고서자료구조 04 최종 보고서
자료구조 04 최종 보고서pkok15
 
연결리스트 박진호
연결리스트 박진호연결리스트 박진호
연결리스트 박진호jinho park
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐S.O.P.T - Shout Our Passion Together
 
이산치수학 Project4
이산치수학 Project4이산치수학 Project4
이산치수학 Project4KoChungWook
 
자료구조 Project5
자료구조 Project5자료구조 Project5
자료구조 Project5KoChungWook
 
데이터분석의 길 3 “r 워크플로우 (스토리텔링)”
데이터분석의 길 3   “r 워크플로우 (스토리텔링)”데이터분석의 길 3   “r 워크플로우 (스토리텔링)”
데이터분석의 길 3 “r 워크플로우 (스토리텔링)”Jaimie Kwon (권재명)
 
[Swift] Data Structure - Binary Tree
[Swift] Data Structure - Binary Tree[Swift] Data Structure - Binary Tree
[Swift] Data Structure - Binary TreeBill Kim
 
Project#3다항식의연산 Hwp
Project#3다항식의연산 HwpProject#3다항식의연산 Hwp
Project#3다항식의연산 HwpKimjeongmoo
 
자료구조3보고서
자료구조3보고서자료구조3보고서
자료구조3보고서KimChangHoen
 
학교에서 배우지 않는 C
학교에서 배우지 않는 C학교에서 배우지 않는 C
학교에서 배우지 않는 CHeesuk Kang
 
Doxygen 사용법
Doxygen 사용법Doxygen 사용법
Doxygen 사용법YoungSu Son
 
변수 이름의 효과
변수 이름의 효과변수 이름의 효과
변수 이름의 효과민욱 이
 
2012 Ds A1 05
2012 Ds A1 052012 Ds A1 05
2012 Ds A1 05seonhyung
 
자료구조 Project2
자료구조 Project2자료구조 Project2
자료구조 Project2KoChungWook
 

Ähnlich wie 자료구조04 (20)

자료구조 트리 보고서
자료구조 트리 보고서자료구조 트리 보고서
자료구조 트리 보고서
 
2012 Ds 04
2012 Ds 042012 Ds 04
2012 Ds 04
 
자료구조 04 최종 보고서
자료구조 04 최종 보고서자료구조 04 최종 보고서
자료구조 04 최종 보고서
 
DS_04
DS_04DS_04
DS_04
 
연결리스트 박진호
연결리스트 박진호연결리스트 박진호
연결리스트 박진호
 
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
[SOPT] 데이터 구조 및 알고리즘 스터디 - #04 : 트리 기초, 이진 트리, 우선순위 큐
 
이산치수학 Project4
이산치수학 Project4이산치수학 Project4
이산치수학 Project4
 
자료구조 Project5
자료구조 Project5자료구조 Project5
자료구조 Project5
 
데이터분석의 길 3 “r 워크플로우 (스토리텔링)”
데이터분석의 길 3   “r 워크플로우 (스토리텔링)”데이터분석의 길 3   “r 워크플로우 (스토리텔링)”
데이터분석의 길 3 “r 워크플로우 (스토리텔링)”
 
[Swift] Data Structure - Binary Tree
[Swift] Data Structure - Binary Tree[Swift] Data Structure - Binary Tree
[Swift] Data Structure - Binary Tree
 
Project#3다항식의연산 Hwp
Project#3다항식의연산 HwpProject#3다항식의연산 Hwp
Project#3다항식의연산 Hwp
 
자료구조3보고서
자료구조3보고서자료구조3보고서
자료구조3보고서
 
학교에서 배우지 않는 C
학교에서 배우지 않는 C학교에서 배우지 않는 C
학교에서 배우지 않는 C
 
Doxygen 사용법
Doxygen 사용법Doxygen 사용법
Doxygen 사용법
 
자구2번
자구2번자구2번
자구2번
 
변수 이름의 효과
변수 이름의 효과변수 이름의 효과
변수 이름의 효과
 
2012 Ds 03
2012 Ds 032012 Ds 03
2012 Ds 03
 
2012 Ds A1 05
2012 Ds A1 052012 Ds A1 05
2012 Ds A1 05
 
자료구조 Project2
자료구조 Project2자료구조 Project2
자료구조 Project2
 
3. linked list
3. linked list3. linked list
3. linked list
 

자료구조04

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