2016-11-13 1 views
0

배열의 숫자 목록을 거쳐 이진 검색 트리에 삽입하는 작은 프로그램을 작성하려고합니다. 여기에 내가 가진 무엇 :초기화되지 않은 값을 함수로 구문 분석

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

typedef struct node_t node_t; 

struct node_t { 
    int data; 
    node_t *left; 
    node_t *right; 
}; 

int insert(node_t *node, int n); 

int main(void) { 
    int array[8] = {5, 8, 3, 6, 9, 2, 4, 7}; 
    int i; 
    node_t *root; 

    for (i = 0; i < 8; i++) { 
     insert(root, array[i]); 
    } 

    return 0; 
} 

int insert(node_t *node, int n) { 

    if (node == NULL) { 
     node = malloc(sizeof node); 
     node->data = n; 
     return 1; 
    } 

    if (n > node->data) { 
     insert(node->left, n); 

    } else if (n < node->data) { 
     insert(node->right, n); 

    } else { 
     return -1; 
    } 

    return 0; // Suppress 'control reaches end of non-void function' 
} 

내가 GCC로 컴파일 할 때 내가 말하는 경고 얻을 " '루트'를이 함수에서 초기화되지 않은 사용할 수 있습니다." 이 (적어도 Windows에서) 오류에 원인이 실행하지만, main()root->data를 인쇄하여 산출 입력 노드에 대한 포인터가 그래서 NULL 있다면 내가 구현하려고했던 생각이 insert() 기능이 확인 된 0

그것을 malloc 할 수 있습니다. 또한 재귀가 처리되는 방식 때문에 삽입되는 숫자가 해당 노드에 삽입되어야합니다. 노드가 NULL과 같지 않으면 숫자를 삽입해야하는 노드의 측면에서 재귀 적으로 insert()을 호출합니다.

이것이 작동하지 않는 이유는 포인터과 관련이 없으며 root->left/root->right이 아니지만이 문제를 해결하기 위해 무엇을 할 수 있는지 알지 못합니다. 어떤 도움을 주시면 감사하겠습니다. 감사합니다!

+0

재귀 호출의 반환 값은 어떻게됩니까? –

+1

문제에 대해서는 c *에서 참조로 * 에뮬레이트 통과를 검색하십시오. –

+0

@Someprogrammerdude 오른쪽 문제 해결을 위해 저의 잘못된 지점에서 코드를 가져 와서 죄송합니다.검색이 진행되는 동안 뭔가 빠졌을 수도 있지만 Google의 3 대 결과는 도움이되지 않는 것 같습니다. 포인터를 전달하는 반면 초기화 된 변수의 주소를 함수로 전달하는 것에 대한 이야기 ​​인 것처럼 보입니다. 무엇을 저장할 지 말하지 않은 주소. – Arkantos

답변

1

게시 한 코드에 더 많은 문제가있을 수 있지만 아래에 몇 가지 문제가 나열되어 있습니다. 이를 위해

if (node->data == NULL) { 

: 그것은 당신이 NULL이 포함 된 경우에 메모리를 할당하는 데 필요한 노드이기 때문에

, 당신은이를 변경해야 또한

if (node == NULL) { 

, 당신은 시작해야 루트 노드는 그 순간에 스택에있는 모든 것을 포함 할 것이고 NULL이 될 수도 있고 그렇지 않을 수도 있습니다 (삽입 함수에서 비교하려는 것).

node_t *root = NULL; 

마지막 일이 기능은 calloc하는 malloc을 변경하는 것입니다 (또는 별도로 메모리 제로에 memset 함수를 수행) : 그래서 지금처럼 시작합니다. 그렇지 않으면 node-> left 및 node-> right 변수에는 초기화되지 않은 메모리를 사용하는 비 NULL 값이 포함될 수 있습니다.

+0

의견을 보내 주셔서 감사합니다. 예, 제가 생각하기에 게시하기 전에 먼저 그 일을 발견했습니다. 나는 당신이 말한 두 가지 다른 것을 바꿨으며, 이제는 오류를 반환하지 않습니다. 그러나 for 루프 다음에 main으로 들어가서'printf ("% d \ n", root-> data);를 시도하면 에러 메시지없이 프로그램이 충돌합니다. 무슨 일이 일어나고 있는지 아시겠습니까? – Arkantos

+0

함수 내에서 해당 메모리 부분을 수정하려면 주소를 메모리로 전달해야한다는 점에 유의하십시오. 즉, 이중 포인터를 사용해야합니다. 그렇지 않으면 삽입 함수가 쓸모 없게됩니다. – staringlizard

1

실제로 프로그램에서 함수에 변수 root을 초기화하지 않습니다. 그러나 root을 초기화하더라도 여전히 트리를 채우려면 main()에서 포인터 root을 수정할 수 있기를 원하기 때문에 포인터를 포인터에 전달해야하기 때문에 으로 문제가 발생합니다. 마찬가지로 에 대한 인수를 에 대한 재귀 호출로 수정해야합니다.

나는 실제로 insert()의 반환 값을 사용하지 않는다는 것을 알았습니다. 그래서, 그것은 단지 void 함수 일 수 있습니다. 몇 가지 문제를 설명하기 위해 코드 내 주석을 추가했습니다.

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

typedef struct node_t node_t; 

struct node_t { 
    int data; 
    node_t *left; 
    node_t *right; 
}; 

void print(node_t *r) { /* In order tree traversal. Gives the sorted output. */ 
    if (!r) return; 
    print(r->left); 
    printf("%d ", r->data); 
    print(r->right); 
} 

void insert(node_t **node, int n); 

int main(void) { 
    int array[] = {5, 8, 3, 6, 9, 2, 4, 7};  /* Removed the size. It can be calculated using sizeof and helps when array size changes */ 
    int i; 
    node_t *root = NULL; 

    /* Without hard-coding, array size can be calculated like this. */ 
    for (i = 0; i < sizeof array/sizeof array[0]; i++) { 
     insert(&root, array[i]); 
    } 

    print(root); 
    return 0; 
} 

void insert(node_t **node, int n) { 
    if (*node == NULL) { 
     *node = malloc(sizeof *node); 
    if (*node == NULL) { /* Need to check the return value for failure. */ 
      perror("malloc"); 
      exit(1); 
     } 
    (*node)->left = (*node)->right = NULL; 
     (*node)->data = n; 
    return; 
    } 

    if (n < (*node)->data) /* Insert smaller elements on the left for it to be a binary tree - but not neccessary */ 
     insert(&(*node)->left, n); 
    else /* Another else below this isn't needed. There can't be any error with the number 'n' itself */ 
     insert(&(*node)->right, n); 
} 
+0

답장을 보내 주셔서 감사합니다! 나는 당신의 프로그램을 실행하려고했지만 괜찮 았지만 컴파일 할 때 오류 메시지없이 충돌했다. (나는 윈도우에있다.) 멀리 포인터 물건에 대한 포인터까지, 그것을 정리 주셔서 감사합니다! 내가 전에 우연히봤을 때 그것은 내가 건너 온 방식 이었지만 옳기에 너무 지저분 해 보였지만 결국 그럴 것 같다. 어쨌든, 충돌에 대해 내가 할 수있는 일이 있습니까? – Arkantos

+0

@Arkantos 기존 프로그램을 수정 했습니까? 내가 게시 한 코드에는 아무런 문제가 없습니다. 아마, 내 제안으로 프로그램을 수정하려고했지만 ('node_t * root = NULL;'과 같은) 일부를 빠뜨린 것입니까? 어쨌든 디버거를 통해 충돌을 일으키는 코드 줄을 찾을 수 있습니다. –

관련 문제