Print all alternating nodes of a linked list

Viewed 79

I'm trying to go through a linked list and print all the alternating nodes at once. I'm not allowed to create a second list/array to store all the alternate nodes values. So far I have been able to go through the alternating nodes with the code below. However it will keep printing the value as it is looping through the nodes...

let's say the list is [1, 2, 3, 4]

NodeT *p;
NodeT *a;
p = list;
while (p != NULL)
{
    printf("p is %d-->", p->data);
    a = p->next;
    printf("a is %d-->", a->data);
    p = p->next->next;
}

The current result is: p is 1-->a is 2-->p is 3-->a is 4-->

The result that I'm looking for is:

p is 1-->3 a is 2-->4

is there any way to achieve this without creating any new list/array?

3 Answers

You should update the pointer p and check that a is not NULL before accessing the fields of a.

Here is a modified version:

void print_alternating_nodes(NodeT *list) {
    NodeT *p;
    NodeT *a;
    p = list;
    while (p != NULL) {
        printf("p is %d --> ", p->data);
        a = p = p->next;
        if (a) {
            printf("a is %d --> ", a->data);
            p = p->next;
        }
    }
}

You cannot hope to produce that output with one loop, since you want to print first all nodes at odd positions, and only after that all nodes at even positions. So use two loops, or even better: create a function that does the looping and printing, and call it twice -- once with list and a second time with list->next:

void printAlternating(NodeT *p) {
    while (p != NULL) {
        printf("%d-->", p->data);
        p = p->next;
        if (p == NULL) break;
        p = p->next;
    }
    printf("NULL\n");
}

Use the above function as follows:

    printf("p is ");
    printAlternating(list);
    printf("a is ");
    printAlternating(list == NULL ? NULL : list->next);

A fully working program:

#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node *next;
} NodeT;

NodeT *createNode(int data, NodeT *next) {
    NodeT *p = malloc(sizeof (NodeT));
    p->data = data;
    p->next = next;
    return p;
}

void printAlternating(NodeT *p) {
    while (p != NULL) {
        printf("%d-->", p->data);
        p = p->next;
        if (p == NULL) break;
        p = p->next;
    }
    printf("NULL\n");
}

int main() {
    NodeT *list = createNode(1, 
                  createNode(2,
                  createNode(3,
                  createNode(4, NULL))));

    printf("p is ");
    printAlternating(list);
    printf("a is ");
    printAlternating(list == NULL ? NULL : list->next);
}

Output:

p is 1-->3-->NULL
a is 2-->4-->NULL

Done using c++ list (to save having to write a list implemenatin) but same idea can be done in c. Just read ahead a bit.

std::list<int> l{1,2,3,4,5,6};
auto it = l.begin();
int a = *it++; // should really test for 0 or 1 element only in list
int b = *it++;

while (it != l.end())
{
    int c = *it++;
    std::cout << a << "->" << c << "\n";
    a = b;
    b = c;
}

output

1->3
2->4
3->5
4->6
Related