1

I got an idea when i started to learning linked lists. My idea was this. I want to insert 1,2,5 to a linked list. And in another field of linked list I want to add 2 digit numbers that starts with 1,2,5. You can see from image. ( C means combinations ) https://i.stack.imgur.com/w1QMj.jpg

int main() {
struct Node* head = NULL;
insertEnd(&head,1);
insertEnd(&head,2);
insertEnd(&head,5);
printLinkedList(head);
insertStartsWith(&head,5,51);
insertStartsWith(&head,5,52);
insertStartsWith(&head,5,53);
insertStartsWith(&head,5,54);
insertStartsWith(&head,1,11);
insertStartsWith(&head,1,12);
insertStartsWith(&head,1,13);
insertStartsWith(&head,1,14);
insertStartsWith(&head,2,21);
insertStartsWith(&head,2,22);
insertStartsWith(&head,2,23);
insertStartsWith(&head,2,24);
printLinkedListWithStartsWith(head);}

My node structure:

struct Node {
int data;
struct Node* next;
struct Node* startsWith; };

My code for inserting initial linked list 1,2 and 5:

void insertEnd(struct Node **pNode, int data){
struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
struct Node *lastNode=*pNode;
newNode->data=data;
newNode->next=NULL;
if (*pNode==NULL)
{
    *pNode=newNode;
    return;
}
while (lastNode->next!=NULL){
    lastNode=lastNode->next;
}
lastNode->next=newNode;
return; }

This part is search number and insert 2 digit numbers to it's startsWith node.

void insertStartsWith(struct Node **pNode, int i, int i1) {
struct Node *tempNode=*pNode;
while (tempNode->next!=NULL){
    if (tempNode->data==i){
        struct Node *tempNode1=tempNode->startsWith;
        while (tempNode1->next!=NULL){
            tempNode1=tempNode1->next;
        }
        struct Node* newNode=(struct Node*)malloc(sizeof(struct Node));
        newNode->data=i1;
        newNode->next=NULL;
        tempNode1->next=newNode;
        return;
    }
    tempNode=tempNode->next;
} }

I add 1 2 and 5 to my linked list. But when I try to add combinations it fails. Where should I look for linked list inside a linked list?

edit 08.18.19

void printLinkedListWithStartsWith(struct Node *pNode) {
printf("Linked list with starts: ");
while (pNode!=NULL) {
    printf("%d \n",pNode->data);
    while(pNode->startsWith!=NULL){
        printf("%d ",pNode->startsWith->data);
        pNode->startsWith=pNode->startsWith->next;
    }
    pNode=pNode->next;
} }
Zopcuk App
  • 71
  • 5
  • You never initialize `startsWidth`. This means `while (tempNode1->next!=NULL)` dereferences an uninitialized pointer. If you initialize correctly to `NULL` here you would need to check for `NULL` before dereferencing. – Gerhardh Aug 16 '19 at 10:46
  • "It fails" is not a useful description. Please read [how to ask](https://stackoverflow.com/help/how-to-ask) and tell us what you expect and what you got instead. How did you check? Did you check values in debuffer of only check output of `printLinkedListWithStartsWith` which you didn't chow us BTW. – Gerhardh Aug 16 '19 at 10:52
  • Oh, and you could improve the readability of your code drastically by applying some proper indentation. – Gerhardh Aug 16 '19 at 10:53
  • Thou shalt not cast the return value of `malloc()` in C: https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – mfro Aug 18 '19 at 05:51

2 Answers2

0

In the function insertEnd you have to initialize all data members of the structure Node.

Function insertStartsWith has undefined behavior. The expression *pNode can be equal to NULL. So in this statement

while (tempNode->next!=NULL){

there is an attempt to access memory using a null-pointer.

Moreover this while loop

while (tempNode->next!=NULL)

does not make sense because for the first node tempNode->next can be equal to NULL but the function does nothing in this case. It just exits the loop an returns the control to the calling function.

What you need to do is to find a node with the value i and if such a node is found then call the function insertEnd passing pointer to the data member startsWith of the found node and the value of the variable ii.

The function can look the following way.

int insertStartsWith(struct Node **pNode, int i, int i1) 
{
    while ( *pNode != NULL && ( *pNode )->data != i ) pNode = &( *pNode )->next;

    int success = *pNode != NULL;

    if ( success )
    {
        insertEnd( &( *pNode )->startsWith, ii );
    }

    return success;
}

If a node with the value of the variable i is not found then an alternative approach is to create such a node. For example

void insertStartsWith(struct Node **pNode, int i, int i1) 
{
    while ( *pNode != NULL && ( *pNode )->data != i ) pNode = &( *pNode )->next;

    if ( *pNode == NULL )
    {
         *pNode = malloc( sizeof( struct Node ) );
         ( *pNode )->data = i;
         ( *pNode )->next = NULL;
         ( *pNode )->startsWith = NULL;
    }

    insertEnd( &( *pNode )->startsWith, ii );
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

Using two structs in each other for linked list of linked lists makes it clear:

typedef struct List List;
typedef struct Node Node;

struct Node{
    size_t size;
    int value;
    Node* node;
    List *list_value;

};

struct List{
    size_t size;
    Node* node;
};

And you can write functions to insert data into lists:

//Inserts list into listP
void list_set_list_value(List* listP, size_t index, List * list_valueP){
        (*listP).node[index].list_value=list_valueP;
}

//Inserts value into listP
void list_set_int_value(List* listP, size_t index, int valueP){
        (*listP).node[index].value=valueP;
}
Ignatius
  • 2,745
  • 2
  • 20
  • 32