본문 바로가기

공부/C++

오늘 짠 알고리즘

아침 3시 30분에 기상해서

4시까지 뭉기적 대며 정신 못차리다가 시작한 과제

과제의 내용은.

입력받은 문자열을 2진트리에 집어넣고 3가지 순회방법으로 출력하시오.

코드는 다음과 같다.
////////////////////
 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <sys/stat.h>



//TreeNode 구조체를 설정한다.

typedef struct TreeNode{

        char data;

        struct TreeNode *left, *right;

}TreeNode;


void inorder(TreeNode *p)

{

 if (p->left != NULL)

  inorder(p->left);


        printf("%c", p->data);  // visit(방문)


 if (p->right != NULL)

  inorder(p->right);


}



void preorder(TreeNode *p)

{


        printf("%c", p->data);  // visit(방문)


 if (p->left != NULL)

  preorder(p->left);


 if (p->right != NULL)

  preorder(p->right);


}



void postorder(TreeNode *p)

{

if (p->left != NULL)

  postorder(p->left);


if (p->right != NULL)

  postorder(p->right);


printf("%c", p->data);  // visit


}

// data 를 이진 탐색 트리 root 에 삽입한다.

// data 가 이미 root안에 있으면 삽입되지 않는다.


void insert_node(TreeNode **root, char data)

{

        TreeNode *p, *t;  // 부모노드와 현재노드

        TreeNode *n;     // 새로운 노드

        

        t = *root; //현재노드에는 인수로 가져온 노드를 복사한다.

        p = NULL; //부모노드에는 널값을 입력한다.

        

//탐색을 먼저 수행


        while( t != NULL) // 현재 노드가 널값이면

        {

                if( data == t->data) return;  // 가져온 데이터와 현재 노드의 데이터가 같으면 종료한다.

                p = t;                           // 부모노드에 현재노드를 복사한다.

                if( data < t-> data) t= t->left; // 만약 가져온 데이터가 현재노드의 값보다 작으면 현재노드 값에 현재노드의 왼쪽을 삽입한다.

                else t = t->right;      //그렇지 않을 경우 현재노드의 오른쪽을 삽입한다.

        }

        // data 가 트리 안에 없으므로 삽입 가능


        n = (TreeNode*)malloc(sizeof(TreeNode));

        if(n == NULL) return; //n 의 값이 널이 되면 종료한다.

        //데이터 복사

        n ->data = data;            //새 노드의 데이터 값에 데이터를 넣는다.

        n ->left = n->right = NULL;  //새 노드의 왼쪽과 오른쪽 값에 널을 넣는다.

        //부모 노드와 링크 연결

        if(p!=NULL)                       // 부모노드가 널이 아니면

                if(data < p->data)           // 데이터가 부모의 데이터 보다 작을 경우

                        p ->left = n;               // 부모의 왼쪽에 n을 넣는다.

                else p -> right = n;            //그렇지 않을 경우 오른쪽에 넣는다.

        else *root = n;                 //부모가 널이 맞으면 가져온 루트포인터에 새 노드를 넣는다.

}





int main(int argc, char *argv[])

{

        TreeNode *Tre;

        int i=0;

        char treechar[100];


        if(argc == 0 || argv[1] == NULL)

        {

                printf("트리에 저장할 문자를 입력하지 않으셨습니다.\n");

                exit(0);

        }


        strncpy(treechar, argv[1], argc); //입력받은 문자들을 treechar에 복사.


        for(i=0; i<argc; i++)

        {

                insert_node(&Tre, treechar[i]);

                //treechar에서 입력받은 문자의 길이만큼 추출하여 트리에 삽입.

        }




//3종류의 순회를 실행하고 그 값을 나타낸다.

printf("preorder :");

preorder(Tre);

printf("\n");


printf("inorder :");

inorder(Tre);

printf("\n");


printf("postorder :");

postorder(Tre);

printf("\n");



        return 0;

}

 

/////////////////

하지만 이 코드는 올바른 값이 나오지 않는다.

왜냐면 메인에서 잘못된 값을 입력하였기 때문이다.

그 잘못된 문구는 교수님께 직접 질문하여 알아내었는데..

        strncpy(treechar, argv[1], argc); //입력받은 문자들을 treechar에 복사.


        for(i=0; i<argc; i++)

바로 이 부분이다

여기에서 argc는 파일 실행단어 와 입력한 문자열 의 2개로 숫자로 2가 입력된다.

즉 입력받은 문자들중 2번째 까지만 입력에 포함되고

for문도 마찬가지로 2회만 돌게 되어있어서 잘못된 값이 나오게 된다.

일단 나의 경우는 저기 있는 오류를 발견하지 못하여 다른 방법을 사용하였는데 그것은 바로

파일명 이후에 쓰지 않고 파일 실행 후에 입력을 다시 받는 것이다.

그 코드는 다음과 같다.

 

int main()

{

        TreeNode *Tre;

        int i=0, su=0;

        char treechar[100]={0};


        printf("트리에 넣을 값을 입력하십시오.\n");


        scanf("%s", &treechar[0]);

        

        su = strlen(treechar);


        if(su == 0)

        {

                printf("트리에 저장할 문자를 입력하지 않으셨습니다.\n");

                exit(0);

        }


        for(i=0; i<su; i++)

        {

                insert_node(&Tre, treechar[i]);

                //treechar에서 입력받은 문자의 길이만큼 추출하여 트리에 삽입.

        }


바뀐 코드는 위와 같다.

하지만 저리 바꾸지 않고 교수님께 지적받은 것을 고친다면 간단하게 할 수 있다.

        strcpy(treechar, argv[1]); //입력받은 문자들을 treechar에 복사.  argc를 지워버리고 strcpy를 사용하였다. 


        for(i=0; i<length(treechar); i++)  // treechar 의 문자열 길이를 추출하여 for문에 기입

오늘의 교훈은..

독학도 좋지만 모르는건 확실하게 아는 사람에게 물어보는 것이 도움된다. 라는 것.