2013-06-08 3 views
2

현재 C에서 균형 B 트리를 구현 중입니다. 이중 연결 목록을 사용하기로 결정했지만 몇 가지 문제가 있습니다. 분명히 포인터 유형이 호환되지 않기 때문에 현재 94, 95 및 96 행에 대해 경고를받습니다. 나는 정말로 어떻게 도움이 될지 모르지만 크게 도움이 될 것입니다.이중 연결 목록 : 호환되지 않는 포인터 유형

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

typedef struct { 
    int data1; 
    int data2; 
    int data2exists; // no: 0 , yes: 1 
    struct node * parent; 
    struct node * left; 
    struct node * middle; 
    struct node * right; 
} node; 

node * insert(int *, node *, node *); 
void getInput(int *); 
node * createNode(int *); 
void quickSwap(node *, int *, int *, int *, int *); 
node * splitLeaf(int *, int *, int *, node *, node *); 
void printTree(node *); 

void main() { 
    int input; 
    getInput(&input); 
    node * root = createNode(&input); 
    getInput(&input); 
    insert(&input, root, root); // returns current pos 
    getInput(&input); 
    insert(&input, root, root); // returns current pos 
    getInput(&input); 
    insert(&input, root, root); // returns current pos 
    printTree(root); 
} 

node * insert(int * input, node * root, node * currentPos) { 
    printf("data1: [%i], data2: [%i], d2exists: [%i], input: [%i]\n", currentPos->data1, currentPos->data2, currentPos->data2exists, *input); 
    if (currentPos->left == NULL && currentPos->middle == NULL && currentPos->right == NULL) { 
     // no children 
     if (*input > currentPos->data1 && currentPos->data2exists == 0) { 
      // data1 < input, no data2 

      currentPos->data2 = *input; 
      currentPos->data2exists = 1; 
      return(currentPos); 
      // printf("CASE1: data1 < input, no data2, no children\n"); 
     } 
     if (*input < currentPos->data1 && currentPos->data2exists == 0) { 
      // data1 > input, no data2 

      currentPos->data2 = currentPos->data1; 
      currentPos->data1 = *input; 
      currentPos->data2exists = 1; 
      return(currentPos); 
      // printf("CASE2: data1 > input, no data2, no children\n"); 
     } 
     if (currentPos->data2exists == 1) { 
      // data2 exists 
      int smallest; 
      int middle; 
      int largest; 
      quickSwap(currentPos, input, &smallest, &middle, &largest); 
      printf("s: [%i] m: [%i] l: [%i]\n", smallest, middle, largest); 
      root = splitLeaf(&smallest, &middle, &largest, currentPos, root); 
     } 
    } 
    return(currentPos); 
} 

void printTree(node * root) { 
    if (root->parent != NULL) { 
     printf("printTree() did not receive root!!!!\n"); 
     return; 
    } 
    else { 
     printf("%i || %i", root->data1, root->data2); 
     printf("\n"); 
     // printf("%i || %i", root->left->data1, root->left->data2); 
     // printf("\t\t"); 
     // printf("%i || %i", root->middle->data1, root->middle->data2); 
     // printf("\t\t"); 
     // printf("%i || %i", root->right->data1, root->right->data2); 
     // printf("\n"); 
    } 
} 

node * splitLeaf(int * smallest, int * middle, int * largest, node * currentPos, node * root) { 
// this function needs to return root! 
    if (currentPos->parent == NULL) { 
     // currentPos is root 
     // create a parent with median 
     node * root = createNode(middle); 
     node * left = createNode(smallest); 
     node * middle = createNode(largest); 
     // genau hier gehts weiter! hier müssen root, left und, middle verknüpft werden! 
     root->left = left; 
     root->middle = middle; 
     left->parent = middle->parent = root; 
     // printf("root-addr: %i, left->parent: %i\n", root, left->parent); 
     return(root); 
    } 
} 

void quickSwap(node * currentPos, int * input, int * smallest, int * middle, int * largest) { 
    // writes values to *smallest, *middle and *largest ordered by size 

    if (currentPos->data1 > currentPos->data2) { 
     *smallest = currentPos->data2; 
     *middle = currentPos->data1; 
    } 
    else { 
     *smallest = currentPos->data1; 
     *middle = currentPos->data2; 
    } 
    if (*input < *smallest) { 
     *largest = *middle; 
     *middle = *smallest; 
     *smallest = *input; 
    } 
    else if (*input < *middle) { 
     *largest = *middle; 
     *middle = *input; 
    } 
    else { 
     *largest = *input; 
    } 
} 

node * createNode(int * input) { 
    node * ptr = (node*) malloc(sizeof(node)); 
    ptr->data1 = * input; 
    ptr->data2 = 0; 
    ptr->data2exists = 0; 
    ptr->parent = NULL; 
    ptr->left = NULL; 
    ptr->middle = NULL; 
    ptr->right = NULL; 
    return(ptr); 
} 

void getInput(int * input) { 
    printf("Enter a number\n"); 
    scanf(" %i",input); 
} 
+0

(어쩌면 당신은 아직 기능을 완료하지 않은하지만) 당신은 (-Wall -pedantic''컴파일 할 때이 경고를 제공 @quinxorin

  • splitLeaf는 아무것도 반환하지 않는 항상 활성화해야합니다). – Kninnug

  • +0

    아니오 - 심지어 벽이나 - 페데 넌스가 없어도. 제가 설치를 할 때 뭔가 이상한 점이 없었습니다. -Wall을 사용하면 gcc에 의해 발생한 약 100 개의 경고가 나타납니다. – smoelge

    +0

    아, 맞아요. GCC를 다시 설치할 수 없으면,'-Wall'과'-pedantic'은 매우 유용합니다. (기본적으로 GCC 내부에서 활성화되어야합니다). – Kninnug

    답변

    5

    아하! 문제는 까다로운 문제입니다. 그것은 당신의 node 구조체의 정의와 관련이 있습니다. 회원 parent, left, middleright의 유형은 struct node이지만 typedefnode으로 직접 작성했습니다. 내 생각 엔 GCC가 정의되지 않은 struct node을 무시하고 다른 곳에서 정의되기를 기대한다.

    즉, node 유형이 있지만 struct node 유형은 없습니다. 따라서 nodestruct node에 할당하려고 할 때 GCC는 무엇을해야할지 모릅니다. 이 유형 node보다 struct node에 대한 다른 이름을 사용하는 것이 현명 할 수도 있지만 그래서

    typedef struct node { 
        ... 
    } node; 
    

    typedef struct { 
        ... 
    } node; 
    

    을 변경합니다.

    일부 nitpicks :

    • GCC는 main는이 int (단지 return 0;) splitLeaf에서
    • 당신이 인수 node * middleint * middleroot와 같은를 재 선언하고 반환하지 않습니다 불평. currentPos->parentNULL하지 않을 때
    +0

    고마워요! 나는 이것에 미치고 있었다. 백만 년 동안 이것을 생각하지 않았을 것입니다. – smoelge

    +0

    "* ... 구조 노드에 대해 유형 노드보다 다른 이름을 사용하는 것이 현명 할 수도 있지만 ... *"예, 예, 예! +1 :-) – alk

    +0

    대단히 환영합니다. 이것은'structed'를'typedef하지 말아야하는 또 다른 이유가되었습니다. – Kninnug

    관련 문제