다음 코드에서 이진 트리 수준 순서 순회를 얻을 수없는 이유는 무엇입니까?

ak_ghoul

이진 검색 트리의 수준 순서 순회를 수행하고 최종 결과를 다차원 배열로 반환하려고합니다. 예. 루트 노드2있고 레벨 1의 노드있으면 코드에서와 같이 1,4반환해야 합니다. 나는 데이터 구조가 처음이며 기능을 사용 하는 데에도 명령이 없습니다 . 어떤 도움을 주시면 감사하겠습니다. 감사 :)[[2], [1,4]]returnColumnSizesmalloc

int height(struct TreeNode *h){
    if (h == NULL) return 0;
    int l = height(h->left);
    int r = height(h->right);
    if (l > r)
        return l+1;
    else
        return r+1;
}

int *ordercalc(struct TreeNode *root, int level){
    if (root == NULL) return NULL;
    int i = 0, arr[100];
    if (level == 1)
        arr[i++] = root->val;
    else if(level > 1){
        ordercalc(root->left, level-1);  //decrease the level one per call to print data when it
        ordercalc(root->right, level-1);  // reaches proper level
    }
    return arr;
}

int** levelOrder(struct TreeNode* root, int* returnSize, int** returnColumnSizes){
    if (*returnSize == 0) return NULL;
    **returnColumnSizes = (int **)malloc(*returnSize * sizeof(int *));
    for (int i=0;i<height(root)+1;i++){
        returnColumnSizes[i] = (int *)malloc(sizeof(int) * 10);
        returnColumnSizes[i] = ordercalc(root, i);
    }
    return returnColumnSizes;
}
Ggorlen

height 좋아 보인다.

levelOrder변경되지 않더라도 루프 i<height(root)+1;의 높이를 root반복해서 계산 하지만 괜찮아 보입니다 . 또한 malloc(sizeof(int) * 10);큰 나무에 대해서는 충분히 동적으로 보이지 않습니다 (나중에 다시 설명하겠습니다).

ordercalc재고해야합니다. 함수가 arr[100];스택 프레임에 할당 된 다음

if (level == 1)
    arr[i++] = root->val;

return arr;

높이를 기준으로 레벨을 채우려 고하는 것을 알 수 있습니다. 올바른 아이디어입니다. 하나:

  1. 스택 할당 배열을 반환하는 것은 정의되지 않은 동작입니다. 호출이 반환되면 프레임의 모든 데이터에 액세스 할 수 없습니다. 이 작업을 malloc수행하려면 힙에서 포인터를 반환해야합니다.
  2. arr[i++] = root->val;루트를 배치 arr[0]하지만이 배열에서는 다른 일이 발생하지 않으므로 의도가 명확하지 않습니다.
  3. 100배열 크기에 대한 하드 코딩 은 실수로 보입니다. 확실히이 버퍼를 오버플로 할만큼 충분히 큰 레벨을 가진 트리가 있는데, 루트 너머로 채우려 고한다고 가정합니다. 로 전환 할 때 malloc으로 계획해야 할 것입니다 realloc.

이 함수에서 결과를 반환하는 대신 미리 할당 된 결과 구조에 대한 포인터를 전달하는 것이 가장 간단 해 보입니다.

재 할당 및 크기 관리를 단순화하는 방법은 여러 단계로 문제에 접근하는 것입니다. 다음은 게임 계획입니다.

  1. 나무 높이를 가져옵니다.
  2. 결과 및 열 크기 배열을 트리 높이와 일치하도록 할당합니다.
  3. 두 번째 순회를 수행하고 각 레벨에 대한 결과 열 길이를 설정합니다.
  4. 3 단계에서 결정한 크기와 일치하도록 각 수준을 할당합니다.
  5. 최종 패스를 수행하여 사전 할당 된 결과 수준을 채 웁니다.

코드는 다음과 같습니다.

int height(struct TreeNode *root) {
    if (root) {
        int left = height(root->left);
        int right = height(root->right);
        return 1 + (left > right ? left : right);
    }

    return 0;
}

void set_col_lens(struct TreeNode *root, int *res_col_lens, int depth) {
    if (root) {
        res_col_lens[depth]++;
        set_col_lens(root->left, res_col_lens, depth + 1);
        set_col_lens(root->right, res_col_lens, depth + 1);
    }
}

void fill_levels(struct TreeNode *root, int **res, int *last_items, int level) {
    if (root) {
        int last_item = last_items[level]++;
        res[level][last_item] = root->val;
        fill_levels(root->left, res, last_items, level + 1);
        fill_levels(root->right, res, last_items, level + 1);
    }
}

int **level_order(struct TreeNode *root, int *res_len, int **res_col_lens) {
    if (!root) {
        *res_len = 0;
        return NULL;
    }

    *res_len = height(root);
    int **res = malloc(sizeof(*res) * (*res_len));
    *res_col_lens = calloc(*res_len, sizeof(**res_col_lens));
    int *last_items = calloc(*res_len, sizeof(*last_items));
    set_col_lens(root, *res_col_lens, 0);

    for (int i = 0; i < *res_len; i++) {
        res[i] = malloc(sizeof((*res)[i]) * (*res_col_lens)[i]);
    }

    fill_levels(root, res, last_items, 0);
    free(last_items);
    return res;
}

이것의 한 가지 이점은 문제가 간단하고 뚜렷한 단계로 나뉘어져 있다는 것입니다.

더 자연스러운 또 다른 접근 방식은 대기열을 사용하고 하나의 스택 프레임에서 폭 우선 순회를 수행하는 것입니다. 그런 다음 문제는 C로 큐 추상화를 작성하게되는데, 이는 어렵지 않지만 약간의 소란이 필요합니다.

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

레벨 순서 순회에서 이진 트리를 만드는 방법은 무엇입니까?

분류에서Dev

이진 트리 수준 순서 순회 시간 복잡성

분류에서Dev

Kafka에서 순간 / 실시간 전류 오프셋을 얻을 수없는 이유는 무엇입니까?

분류에서Dev

Haskell은 깊이 우선 순서 순회를 통해 이진 트리에 레이블을 지정합니다.

분류에서Dev

```getStaticProps''`에서 쿼리 매개 변수를 얻을 수없는 이유는 무엇입니까?

분류에서Dev

순수 사용자 수준 스레드 전략에서 다중 스레드 응용 프로그램이 다중 처리를 활용할 수없는 이유는 무엇입니까?

분류에서Dev

Redis 트랜잭션에서 캐시 된 데이터를 얻을 수없는 이유는 무엇입니까?

분류에서Dev

AngularJs 팩토리에서 업데이트 값을 얻을 수없는 이유는 무엇입니까?

분류에서Dev

이 두 쿼리가 서로 다른 순서로 레코드를 검색하는 이유는 무엇입니까?

분류에서Dev

MySQL에서 다른 행으로 결과를 얻을 수없는 이유는 무엇입니까?

분류에서Dev

이 코드에서 "줄을 찾을 수 없음"예외가 발생하는 이유는 무엇입니까?

분류에서Dev

내 코드에서 numba가 순수한 Python보다 느린 이유는 무엇입니까?

분류에서Dev

PDO 연관 배열에서 에코에 대한 정보를 얻을 수없는 이유는 무엇입니까?

분류에서Dev

R Markdown 문서에서 인쇄 할 코드 색상을 얻을 수없는 이유는 무엇입니까?

분류에서Dev

웹 사이트에서 json 버퍼로 json 데이터의 다음 페이지를 읽을 수없는 이유는 무엇입니까?

분류에서Dev

중단 순서가 내 코드의 루프를 중지 할 수없는 이유는 무엇입니까?

분류에서Dev

다음 코드 스 니펫에서 변수 값에 액세스 할 수없는 이유는 무엇입니까?

분류에서Dev

스레드 내 이진 트리의 삽입 또는 순서 순회에서 무엇이 잘못되었는지

분류에서Dev

Angular10의 드롭 다운에서 값을 얻을 수없는 이유는 무엇입니까?

분류에서Dev

/ var / www 이외의 디렉토리에서 사이트를 제공하기 위해 Apache2를 얻을 수없는 이유는 무엇입니까?

분류에서Dev

다음 C ++ 코드에서 메모리 누수가 발생하는 이유는 무엇입니까?

분류에서Dev

다음 자바 스크립트 코드에서 for 루프 내에 6 개의 다른 변수가있을 수있는 이유는 무엇입니까?

분류에서Dev

코드에서 SolidColorBrush 리소스 값을 설정할 수없는 이유는 무엇입니까?

분류에서Dev

Java에서 이중 값을 얻을 수없는 이유는 무엇입니까?

분류에서Dev

인수에 대한 jackOptions () 메서드를 찾을 수 없습니다. 이유는 무엇입니까?

분류에서Dev

다음 코드에서 정적 변수를 사용하는 이유는 무엇입니까?

분류에서Dev

IL 코드에서 델리게이트의 Invoke 메서드 본문을 찾을 수없는 이유는 무엇입니까?

분류에서Dev

g ++에서 내 소스 코드를 찾을 수없는 이유는 무엇입니까?

분류에서Dev

@Async 메서드에서 결과를 다시 얻을 수없는 이유는 무엇입니까? ( "IllegalStateException : EntityManagerFactory가 닫힘"이 발생 함)

Related 관련 기사

  1. 1

    레벨 순서 순회에서 이진 트리를 만드는 방법은 무엇입니까?

  2. 2

    이진 트리 수준 순서 순회 시간 복잡성

  3. 3

    Kafka에서 순간 / 실시간 전류 오프셋을 얻을 수없는 이유는 무엇입니까?

  4. 4

    Haskell은 깊이 우선 순서 순회를 통해 이진 트리에 레이블을 지정합니다.

  5. 5

    ```getStaticProps''`에서 쿼리 매개 변수를 얻을 수없는 이유는 무엇입니까?

  6. 6

    순수 사용자 수준 스레드 전략에서 다중 스레드 응용 프로그램이 다중 처리를 활용할 수없는 이유는 무엇입니까?

  7. 7

    Redis 트랜잭션에서 캐시 된 데이터를 얻을 수없는 이유는 무엇입니까?

  8. 8

    AngularJs 팩토리에서 업데이트 값을 얻을 수없는 이유는 무엇입니까?

  9. 9

    이 두 쿼리가 서로 다른 순서로 레코드를 검색하는 이유는 무엇입니까?

  10. 10

    MySQL에서 다른 행으로 결과를 얻을 수없는 이유는 무엇입니까?

  11. 11

    이 코드에서 "줄을 찾을 수 없음"예외가 발생하는 이유는 무엇입니까?

  12. 12

    내 코드에서 numba가 순수한 Python보다 느린 이유는 무엇입니까?

  13. 13

    PDO 연관 배열에서 에코에 대한 정보를 얻을 수없는 이유는 무엇입니까?

  14. 14

    R Markdown 문서에서 인쇄 할 코드 색상을 얻을 수없는 이유는 무엇입니까?

  15. 15

    웹 사이트에서 json 버퍼로 json 데이터의 다음 페이지를 읽을 수없는 이유는 무엇입니까?

  16. 16

    중단 순서가 내 코드의 루프를 중지 할 수없는 이유는 무엇입니까?

  17. 17

    다음 코드 스 니펫에서 변수 값에 액세스 할 수없는 이유는 무엇입니까?

  18. 18

    스레드 내 이진 트리의 삽입 또는 순서 순회에서 무엇이 잘못되었는지

  19. 19

    Angular10의 드롭 다운에서 값을 얻을 수없는 이유는 무엇입니까?

  20. 20

    / var / www 이외의 디렉토리에서 사이트를 제공하기 위해 Apache2를 얻을 수없는 이유는 무엇입니까?

  21. 21

    다음 C ++ 코드에서 메모리 누수가 발생하는 이유는 무엇입니까?

  22. 22

    다음 자바 스크립트 코드에서 for 루프 내에 6 개의 다른 변수가있을 수있는 이유는 무엇입니까?

  23. 23

    코드에서 SolidColorBrush 리소스 값을 설정할 수없는 이유는 무엇입니까?

  24. 24

    Java에서 이중 값을 얻을 수없는 이유는 무엇입니까?

  25. 25

    인수에 대한 jackOptions () 메서드를 찾을 수 없습니다. 이유는 무엇입니까?

  26. 26

    다음 코드에서 정적 변수를 사용하는 이유는 무엇입니까?

  27. 27

    IL 코드에서 델리게이트의 Invoke 메서드 본문을 찾을 수없는 이유는 무엇입니까?

  28. 28

    g ++에서 내 소스 코드를 찾을 수없는 이유는 무엇입니까?

  29. 29

    @Async 메서드에서 결과를 다시 얻을 수없는 이유는 무엇입니까? ( "IllegalStateException : EntityManagerFactory가 닫힘"이 발생 함)

뜨겁다태그

보관