c - 双向链表: Incompatible pointer types

标签 c pointers struct doubly-linked-list

目前我正在用 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);
}

最佳答案

啊哈!这是一个棘手的问题。它与 node 结构的定义有关。成员 parentleftmiddleright 的类型为 struct node,但是您直接将结构typedef编辑为node。我的猜测是 GCC 忽略了未定义的 struct 节点并希望它在其他地方定义。

换句话说:node 类型存在,但 struct node 不存在。因此,当您尝试将节点分配给结构节点时,GCC不知道该怎么做。所以改变一下

typedef struct {
    ...
} node;

typedef struct node {
    ...
} node;

尽管为结构节点使用其他名称可能比类型节点更明智。

一些挑剔:

  • GCC 提示 main 不返回 int(只是 return 0;)
  • splitLeaf 中,您将参数 int * middle 重新声明为 node * middle,与 root 相同>.
  • currentPos->parent 不为 NULL 时,
  • splitLeaf 不会返回任何内容(尽管您可能还没有完成该函数) )

关于c - 双向链表: Incompatible pointer types,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17000170/

相关文章:

c++ - boost::interprocess : cout a string variable when iterating through a map that references an object from a struct

结构体中的 C 结构体成员函数

c - 在非规范模式下使用终端 IO 确定按钮边界

c - 使用 C 编程检测 PC 上的电源故障

c++ - 柏林噪声和高度图/位图

C 释放指向指针的指针

c - 带指针的结构的 malloc(重新访问)

java - 通过 JNI 对 C 和 Java 代码使用互斥锁或其他同步方法

C++ 二叉搜索树插入函数

c - 在文件中间添加字符而不覆盖C中现有的字符