2017-11-28 22 views
0

A (왼쪽)와 B (오른쪽)가 이미 가득차면 이진 트리에 노드를 추가하는 방법은 무엇입니까? 균형 잡힌 나무를 만들어야합니다. 그러나 트리에 더 많은 데이터를 추가하는 방법을 알 수는 없습니다. 어떤 도움이라도 대단히 감사하겠습니다.C에서 이진 트리에 노드를 추가하는 방법은 무엇입니까?

미리 감사드립니다.

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

struct node 
{ 
    char *titel; 
    struct node *A; 
    struct node *B; 
}; 

void display(struct node *leaf) 
{ 
    if (leaf != NULL) 
    { 
     display(leaf->A); 
     printf("%s\n",leaf->titel); 
     display(leaf->B); 
    } 
} 

struct node *insert(char* titel, struct node **leaf) 
{ 
    if (*leaf == 0) 
    { 
     *leaf = (struct node*)malloc(sizeof(struct node)); 
     (*leaf)->titel = malloc(strlen(titel)+1); 
     strcpy((*leaf)->titel,titel); 
     (*leaf)->A = NULL; 
     (*leaf)->B = NULL; 
    } 
    else if ((*leaf)->A == NULL) 
    { 
     (*leaf)->A = insert(titel,&(*leaf)->A); 
    } 
    else if ((*leaf)->B == NULL) 
    { 
     (*leaf)->B = insert(titel,&(*leaf)->B); 
    } 
    //WHAT TO ADD HERE TO CREATE ANOTHER NODE? 
    return(*leaf); 
} 

int main(int argc, char const *argv[]) 
{ 
    struct node *root = NULL; 
    insert("root",&root); 
    insert("chapter_1A",&root); 
    insert("chapter_1B",&root); 
    insert("chapter_2A",&root); 
    insert("chapter_2B",&root); 
    insert("chapter_3A",&root); 
    display(root); 
    return 0; 
} 

출력은 균형 잡힌 이진 트리와 같아야합니다. 인쇄하지 말고 메모리에 저장해야합니다.

실제 출력 : (왼쪽)이 경우

chapter_1A 
root 
chapter_1B 

     root 
       /  \ 
      chapter_1A chapter_1B 
     / \ / \ 
     ch_2A ch_2B ch_3A ch_3B 
       and so on. 
+1

나무가 가득 찰 수있는 방법은 무엇입니까? –

+0

정확한 문제는 무엇입니까? 어떤 출력물을 얻고 어떤 출력물을 기대합니까? –

+0

내 트리에 다른 노드를 추가하는 방법을 모르겠습니다. 그게 내 문제 야. 루트 노드를 만들고 루트의 왼쪽과 오른쪽을 채우고 있습니다. 그러나 왼쪽 사이드 노드 또는 오른 쪽 노드에서 다른 브랜치를 생성하는 법을 모르겠습니다. 그게 내 정확한 문제 야. 편집 : 입력을 메인에서 볼 수 있습니다. 출력은 왼쪽에서 오른쪽으로 시작하는 트리 여야합니다. 루트 /\ ch_A1 ch_B1 /\/\ A2 B2의 A3의 B3 단지 균형 이진 검색 트리와 같은 . –

답변

3

가 어떻게 내 이진 트리에 노드를 추가하려면와 B (오른쪽)가 이미 가득?

"전체"로 말하면 두 자식 노드 자체에 두 개의 자식이 있음을 의미합니다. 이 경우 새 노드를 자식의 자식 중 하나에 추가해야합니다. 일반적으로 재귀 함수를 통해이 작업을 수행하므로 어린이의 자식도 "전체"인 경우를 올바르게 처리 할 수 ​​있습니다.

난 그냥 ("균형"이 자체가 몇 가지를 의미 할 수 있습니다. 예를 들어, "높이 균형 '과'무게 균형"나무가

균형 트리를 만들어야합니다. 원하는 것을 지정하지 않았습니다.)

다음 질문은 (전체) 자식이 오른쪽 또는 왼쪽에 새 노드를 추가하는 것입니다. 한 가지 옵션은 각 노드의 전체 자손 수를 유지하고 항상 가장 적은 수의 자식 노드에 추가하는 것입니다.

또 다른 옵션은 트리에있는 노드의 총 수를 유지하고 해당 숫자의 비트 (첫 번째 1 비트 제외)를 사용하여 새 노드를 삽입 할 위치를 결정하는 것입니다. 당신이 5 개 노드 트리가있는 경우 예를 들어, :

    A 
      B   C 
     D E 

새 노드를 추가 이진 110 6에 노드 수를 증가합니다. 먼저 1을 무시하십시오. 다음에 1을 "오른쪽으로 가십시오"(C)와 "0"을 "왼쪽으로"(이것은 C의 왼쪽 하위로 삽입하도록 알려줍니다)로 해석하십시오. 당신이 값을 반환 할 필요가 없기 때문에 내가 void에 반환 형식을 변경

void insert(char* titel, struct node **leaf, int nodeCount, int bitPos) 
{ 
    if (*leaf == 0) 
    { 
    *leaf = (struct node*)malloc(sizeof(struct node)); 
    (*leaf)->titel = malloc(strlen(titel)+1); 
    strcpy((*leaf)->titel,titel); 
    (*leaf)->A = NULL; 
    (*leaf)->B = NULL; 
    } 
    else 
    { 
    int currentBit = (nodeCount >> bitPos) & 1; 
    if (currentBit == 0) { 
     // insert to left 
     insert(titel, &((*leaf)->A), nodeCount, bitPos - 1); 
    } 
    else 
    { 
     // insert to right 
     insert(titel, &((*leaf)->B), nodeCount, bitPos - 1); 
    } 
    } 
} 

주의 사항 : 코드는 다음과 같이된다. 초기 bitPos 값의 계산을 연습으로 남겨 둘 것입니다 (기억하십시오 : 최상위 순위 인 1 비트에서 1 빼기).

트리에서 요소를 제거해야하는 경우에는 다시 균형을 조정할 방법을 찾아야합니다.

삽입 및 삭제를 모두 지원하는 균형 잡힌 트리를 유지 관리하기위한 여러 가지 데이터 구조 및 알고리즘이 있습니다. 예를 들어 red-black treesAVL trees을 참조하십시오.이것들은 일반적으로 정렬 된 트리에 사용되지만, 정렬되지 않은 트리에 맞게 조정해야합니다.

+0

[RedBlackTree - MIT] (http://web.mit.edu/~emin/www.old/source_code/red_black_tree/)와 [AVL Tree - ZenTut] (http : //www.zentut.com/c-tutorial/c-avl-tree/). (리눅스 커널은 두 가지의 좋은 구현을 포함하고 있지만 상당한 수의 매크로를 사용합니다) –

+0

고맙습니다. 하지만 거기에 bitPos의 가치를 계산할 필요없이 높이 균형 이진 트리를 만드는 방법이 아닌가요? –

+0

@GerhardHaid 네, 이미 말했듯이 : AVL 트리 또는 Red-Black 트리를 사용할 수 있습니다. 그러나'bitPos'를 계산하는 것이 왜 문제가되는지 (어떻게해야할지 모르거나 검색을하지 못하거나 적절한 답이없는 경우 질문을하는 것이) 왜 나는 안 보입니다. – davmac