2

My insertion worked, so a new question, How do I set a data to NULL in C? Pls see the last part for illustration.!

I have defined a structure type

typedef struct node {
    char* data;
    int weight;
    bool  end_of_key;
    struct node * left;
    struct node * equal;
    struct node * right;
} node_t;



int main(int argc, char *argv[]){
node_t* root=NULL;
int weight;
int i = 1;

insert(root,"cat",3);
insert(root,"at",2);
insert(root,"cute",4);
.....
return 0 ;}

This is my insert function

node_t*  insert(node_t* pNode,char* word, int weight) {

    /**
    * Create a new pNode, and save a character from word
    */
  pNode = (node_t*)malloc(sizeof(node_t));

if(*pNode->data == NULL){   
        pNode->left = NULL;
        pNode->equal = NULL;
        pNode->right = NULL;
        pNode->data = word;
  }



if (word[0] < *(pNode->data)) {
    /**
    * Insert the character on the left branch
    */
    pNode->left = insert(pNode, word, weight);
}

else if (word[0] == *(pNode->data)) {
    if ((word[1]) == '\0') {
        /**
        *set pNode end_of_key_flag to true and assign weight
        */
        pNode->end_of_key = true;
        pNode->weight = weight;
    //  printf("%c", *(pNode->data++));
    }
    else {
        /**
        * If the word contains more characters, try to insert them
        * under the equal branch
        */
    //  printf("%c", *(pNode->data++));
        pNode->equal = insert(pNode,word + 1, weight);

    }
}

else {
    /**
    * If current char in word is greater than char in pData
    * Insert the character on the right branch
    */
    pNode->right = insert(pNode,word, weight);
}

return pNode;} 

this code is trying to do this enter image description here

So my insertion finally worked but it appears that it can only insert one thing,I am wondering how do I set data to NULL in C?

if(*pNode->data == NULL){   
        pNode->left = NULL;
        pNode->equal = NULL;
        pNode->right = NULL;
        pNode->data = word;
  }

I want to run this four lines of code when *pNode->data is empty but it apparently did not work the way I wanted it to.

Vincent Zhou
  • 141
  • 2
  • 10
  • I don't know, but there's at least one big issue `pNode` isn't modified outside your `insert` function. – Jean-François Fabre Sep 04 '17 at 08:53
  • Also: you cannot make a `char *` out of a `const char *`. Probably explains the "address out of bounds" for the string parameter. – Jean-François Fabre Sep 04 '17 at 08:54
  • 2
    while you're at it, can you show us the exact line where the SEGV occurs (congrats for actually _using_ a debugger in a SO question, that said) – Jean-François Fabre Sep 04 '17 at 08:55
  • 1
    also I don't get why you're trying to insert `c` by passing `"cat"` – Jean-François Fabre Sep 04 '17 at 08:59
  • 4
    2 hours ago you asked this: [initializing linked structure node](https://stackoverflow.com/questions/46031645/initializing-linked-structure-node). Your problems originating from the fact that you have to get a basic understanding of C, especially pointers, C-strings and arrays. I don't want to offend you take the following as an advice: **Learn C properly instead of asking about each problem, you will benefit from it and gain understanding. You will not learn if we fix your code and you don't understand. Learn and fix yourself and try to understand.** – Andre Kampling Sep 04 '17 at 09:02
  • 3
    Possible duplicate of [initializing linked structure node](https://stackoverflow.com/questions/46031645/initializing-linked-structure-node) – Jabberwocky Sep 04 '17 at 09:03
  • @Andre Kampling I tried ur method when I changed char* data to char data and I used pNode->data = word[0] it shows this error I dont know why :( – Vincent Zhou Sep 04 '17 at 09:14
  • @Michael Walz I also tried to allocate memory for pNode->data using pNode->data = (char*) malloc(sizeof(char)); but it still didnt work out – Vincent Zhou Sep 04 '17 at 09:16
  • @VincentZhou what are you _actually_ trying to achieve? Please read this: [XY Problem](http://xyproblem.info/) – Jabberwocky Sep 04 '17 at 09:17
  • @leyanpan It returns pNode, and I want to get the data stored in pNode->data – Vincent Zhou Sep 04 '17 at 09:18
  • @VincentZhou: Read my comment again and **learn the basic C concepts**. StackOverflow [has a C book list](https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list). – Andre Kampling Sep 04 '17 at 09:18
  • @Jean-François Fabre sorry I tried using pNode->data = word[0], does this allow me to insert 'c'? but it shows the same error – Vincent Zhou Sep 04 '17 at 09:19
  • why your linked list contains nodes `left`, `right` and `equal`. what is the logic of filling this list up? – vadim_hr Sep 04 '17 at 09:20
  • Can you confirm that each node contains only one single `char`? What do the nodes `TI2`, `RI2` actually contain? vadim_hr's comment still stands. Explain more. – Jabberwocky Sep 04 '17 at 09:33
  • @ Michael Walz @ vadim_hr pNode->data contains one charcater, 2 stands for the weight contained at pNode->weight which is the number of characters of a word. Im trying to do a ternary serch tree, so here I insert words in the order "cut","at","cute","cure","cat","car","pet" the first line is just the first character of the word.second line is the second character of the word and if it is smaller, go to the left, for example here ,"a" goes to the left of "c", and "p" goes to the right of "c" – Vincent Zhou Sep 04 '17 at 09:40
  • 1
    There are many issues within your code. You should learn how to use a debugger. Problems spotted: `if ((word + 1) == '\0')`-> `if ((word[1]) == '\0')`, `insert(root, xxx, 3);` -> `root = insert(root, xxx, 3);`, `insert` won't modify the `root` parameter. And you don't initialize `weight` and `end_of_key` in all cases. There are probably more problems. – Jabberwocky Sep 04 '17 at 09:54
  • @Michael Walz Thanks a lot ,can u elaborate what do u mean insert won't modify the root parameter? – Vincent Zhou Sep 04 '17 at 10:17
  • 1
    `root = NULL; insert(root, xxx, 3); `; now root will still be `NULL`, parameters are passed by valuen in C. This is absolutely basic C knowledge. – Jabberwocky Sep 04 '17 at 10:35

2 Answers2

1

Some improvements of your code

  • insert() must have first parameter to be node_t ** (see comments)
  • char *data must be char data, because every node contains only one char
  • weight can be calculated when the list is filled up

Here is corrected version of your code. Function get() is used to find the key in the filled up list (for testing).

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

typedef struct node {
    char data;
    int weight;
    struct node * left;
    struct node * equal;
    struct node * right;
} node_t;

void insert(node_t** pNode, char* word, int weight)
{
    char data;
    node_t **pNext;
    node_t *pCurrent;

    if (word == NULL)
    {
        return ;
    }

    data = word[weight];

    if (*pNode == NULL)
    {
        *pNode = malloc(sizeof(node_t));
        pCurrent = *pNode;
        memset(pCurrent, 0, sizeof(node_t));
        pCurrent->data = data;
    }
    else
    {
        pCurrent = *pNode;
    }

    if (data == pCurrent->data)
    {
        weight ++;
        if (strlen(word) == weight)
        {
            pCurrent->weight = weight;
            return;
        }

        pNext = &pCurrent->equal;
    }
    else if (data > pCurrent->data)
    {
        pNext = &pCurrent->right;
    }
    else
    {
        pNext = &pCurrent->left;
    }

    insert(pNext, word, weight);
}

int get(node_t** pNode, char *word, int weight)
{
    char data;
    node_t **pNext;
    node_t *pCurrent;

    if (word == NULL)
    {
        return 0;
    }

    data = word[weight];

    if (*pNode == NULL)
    {
        return 0; // not found
    }

    pCurrent = *pNode;

    if (data == pCurrent->data)
    {
        weight ++;

        if (strlen(word) == weight)
        {
            return pCurrent->weight;
        }

        pNext = &pCurrent->equal;
    }
    else if (data > pCurrent->data)
    {
        pNext = &pCurrent->right;
    }
    else
    {
        pNext = &pCurrent->left;
    }

    return get(pNext, word, weight);
}

int main()
{
    node_t * root = NULL;

    insert(&root, "cat", 0);
    insert(&root, "at", 0);
    insert(&root, "cute", 0);

    printf("cat=%d\n",get(&root,"cat",0)); // cat=3
    printf("at=%d\n",get(&root,"at",0)); // at=2
    printf("cute=%d\n",get(&root,"cute",0)); // cute=4

    // todo: free memory

    return 0;
}

The code is tested except freeing the memory.

vadim_hr
  • 533
  • 5
  • 11
0

First, there is something wrong with your insert() signature (as already pointed by @MichaelWalz )

you'd rather

node_t* insert(node_t** pNode, char* word, int weight);

and then

insert(&root,"cute",4);

why don't you start fixing this and edit your post ?

Gilles Gouaillardet
  • 8,193
  • 11
  • 24
  • 30