1

Method:

  1. Traverse the given list from head to tail and push every visited node to stack.

  2. Traverse the list again. For every visited node, pop a node from stack and compare data of popped node with currently visited node.

  3. If all nodes matched, then return true, else false.

Edit: The program compiles without an error but stops working during run time

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

struct Node
{
int data;
struct Node *next;
};
struct Stack
{
unsigned capacity;
int top;
int * array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack=(struct Stack*)malloc(sizeof(struct Stack));
stack->capacity=capacity;
stack->top=-1;
stack->array=(int *)malloc(sizeof(int)*stack->capacity);
return stack;
}
int isFull(struct Stack* stack)
{   return stack->top == stack->capacity - 1; }

// Stack 
int isEmpty(struct Stack* stack)
{   return stack->top == -1;  }

// stack.
void push(struct Stack* stack, int item)
{
if (isFull(stack))
    return;
stack->array[++stack->top] = item;
printf("%d pushed to stack\n", item);
}

// stack.  
int pop(struct Stack* stack)
{
if (isEmpty(stack))
    return INT_MIN;
return stack->array[stack->top--];
}

//  stack
int peek(struct Stack* stack)
{
if (isEmpty(stack))
    return INT_MIN;
return stack->array[stack->top];
}
// linkedlist
void insert(struct Node** head_ref, int new_data)
{

struct Node* new_node =
        (struct Node*) malloc(sizeof(struct Node));

new_node->data  = new_data;


new_node->next = (*head_ref);


(*head_ref)    = new_node;
}

bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp)
{
    push(stack,temp->data);
    temp=temp->next;
}
while(curr)
{
    if(pop(stack)==curr->data)
    {
       curr=curr->next;
    }
    else
    exit(0);
}
return true;

} 
// Driver program to test above functions
int main()
{
struct Stack* stack = createStack(100);
struct Node* head=NULL;
insert(&head,1);
insert(&head,2);
insert(&head,1);
printf("%s",compare(stack,head));

return 0;
}
Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
Stack
  • 235
  • 3
  • 15
  • @BLUEPIXY that was a silly question but thnx, i edited the question the program stops working in the run time – Stack Jan 07 '15 at 08:18
  • 1
    Still having a compile issue: `error C2065: 'c' : undeclared identifier` for `printf("%s",c=compare(stack,head));` – dbc Jan 07 '15 at 08:23
  • at `compare` : change to `struct Node* temp=head,* curr=head;`. at `main` : change to `printf("%s\n", compare(stack,head) ? "yes" : "no");//never "no" :-)` – BLUEPIXY Jan 07 '15 at 08:40
  • Now write a recursive function to do the same thing. Nested function calls amount to push on a stack and return pop. – Persixty Jan 07 '15 at 08:41
  • @dbc thanx i forgot editing that part here there should not be a 'c =' – Stack Jan 07 '15 at 08:45
  • 3
    indent your code please. – UmNyobe Jan 07 '15 at 08:46
  • The 'stops' at run-time might be because you brutally call `exit(0)` if the list isn't a palindrome! – Persixty Jan 07 '15 at 08:57
  • Instead of using a stack array (which requires you to estimate the maximum list length up front) you could build a doubly-linked list as you traverse the input list, prepending elememnts. Then, you'd just need to walk both lists in parallel and see whether they are equal. – Frerich Raabe Jan 07 '15 at 09:19
  • @FrerichRaabe Thanx fr ur input but i want to implement this in a single linkedlist. – Stack Jan 07 '15 at 09:26
  • how hard is it to compile with warnings enabled? – Jasen Jan 07 '15 at 10:02

4 Answers4

2
struct Node* temp;

temp is not initialized in

bool compare(struct Stack* stack,struct Node* head)

struct Node* temp,* curr=head;

is not

struct struct Node* temp=head,* curr=head;

Using uninitialized variables lead to undefined behavior.

Gopi
  • 19,784
  • 4
  • 24
  • 36
  • @Gopi - the node is being inserted at the beginning of the list, which is fine for this application. – dbc Jan 07 '15 at 08:51
2

You've got an uninitialized local variable temp:

bool compare(struct Stack* stack,struct Node* head)
{
    struct Node* temp,* curr=head;
    while(temp)  // NOT INITIALIZED
    {
        push(stack,temp->data);
        temp=temp->next;
    }
    while(curr)
    {
        if(pop(stack)==curr->data)
        {
            curr=curr->next;
        }
        else
            exit(0);
    }
    return true;
} 

You need to fix that first; I think the following should work:

bool compare(struct Stack* stack,struct Node* head)
{
    struct Node  *curr;

    for (curr = head; curr != NULL; curr = curr->next)
    {
        push(stack, curr->data);
    }

    for (curr = head; curr != NULL; curr = curr->next)
    {
        if (pop(stack) != curr->data)
            return false;
    }
    return true;
} 

Next, you're printing a boolean result with "%s", which is for strings. You need to do something like:

    c=compare(stack,head);
    printf("%d\n", c);

or alternatively

    printf("%s\n", c ? "true" : "false");

At this point, it no longer crashes for me, and works for a couple simple test cases. You might think about how to handle the case of overflowing the stack, and also consider formatting your code to make it more readable.

dbc
  • 104,963
  • 20
  • 228
  • 340
  • The first one works for int c; i.e., it prints 1. The second one also works fine but what should i code so as the output is 'true' other than using the ternary operator? – Stack Jan 07 '15 at 09:37
  • @Stack - There's [no built-in printf format for bool](http://stackoverflow.com/questions/17307275/what-is-the-printf-format-specifier-for-bool), so you'll need to do that manually. – dbc Jan 07 '15 at 09:42
2

Function compare has at least two errors. The first one is that it uses uninitialized pointer temp

bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp) // <= temp is not initialized
{

The second one is that the function never returns false though according to the assignment it has to return false if values in the list and in the stack do not match. Instead of returning false you call function exit

else
exit(0);

I would write the function the following way

bool compare(struct Stack *stack, struct Node *head )
{
    struct Node *current = head;

    for ( ; current != NULL && !isFull( stack ); current = current->next )
    {
        push( stack, current->data );
    }

    current = head;

    while ( current != NULL && !isEmpty( stack ) && pop( stack ) == current->data )
    {
        current = current->next;
    } 

    return current == NULL && isEmpty( stack );
} 

It is the only correct function implementation among presented here function implementations in other answers.:)

As C does not have type bool then that you could use name bool in a program written in C you have to include header <stdbool.h> or define this name yourself as a typedef either of _Bool (if your compiler supports this type) or of int.

You could declare the return type of the function as int if you do not want to include header <stdbool.h>. For example

int compare(struct Stack *stack, struct Node *head );

Take into account that you need to write also functions that will free all allocated memory for the list and the stack.

For example you could free memory allocated for the stack the following way

void freeStack( struct Stack **stack )
{
    if ( *stack != NULL ) free( ( *stack )->array );
    free( *stack );

    *stack = NULL;
}

The same way you could free the memory allocated for the list

void freeList( struct Node **head )
{
    if ( *head != NULL )
    {
        Node *current = ( *head )->next;

        while ( current != NULL )
        {
            Node *temp = current;
            current = current->next;
            free( temp );
        }
    }

    free( *head );

    *head = NULL;
}  
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • why do we return current == NULL && isEmpty( stack ) when the return type is bool and it should return either true or false and also can we return both using && operator? Also in ur code whether the items match or not it prints the return statement? – Stack Jan 07 '15 at 09:52
  • @Stack Expression current == NULL && isEmpty( stack ) contains logical AND operator and its value either true or false. If the list is equal to the stack in the reverse order then the last node of the list shall be equal to NULL and the stack shall be empty because all elements were popped. It is the only correct condition that determinates whether the sequence of nodes is a palindrome. – Vlad from Moscow Jan 07 '15 at 09:57
  • @Stack I am sorry. Because the program is written in C then the value of the expression is either 1 (true) or 0 (false). C has no type bool. In C bool is a type def for _Bool that is an integer type. – Vlad from Moscow Jan 07 '15 at 10:02
  • ur logic is awesome man.. yes this doesn't compile but c has bool type defined in stdbool.h but what should we write so that it compiles – Stack Jan 07 '15 at 10:08
  • The return statement also evaluates to either true or false so what is wrong with this code. Is it the data type? what can we write in place of bool so that it compiles – Stack Jan 07 '15 at 10:10
  • @Stack C has no type bool. C has type _Bool that is an integer type that has two values 0 and 1. In header file bool is defined as a typedef of _Bool. For example typedef _Bool bool; You have to include this header if you want to use this typedef. As for true and false then they are simply integer constants 1 and 0 respectively. – Vlad from Moscow Jan 07 '15 at 10:11
  • @Stack Thus either you have to include header or declare the return type of the function as int. – Vlad from Moscow Jan 07 '15 at 10:13
  • Thanx a lot by the way i had included stdbool as one of the header files in the question u might have missed that.. – Stack Jan 07 '15 at 10:19
  • @Stack I will explain why it is the only correct function implementation.The problem is that function pop returns a value even if the stack is empty. In this case if the list will contain the same values as the value returned by an empty stack then function compare will return incorrecdt result. It will compare empty stack with non-empty list. – Vlad from Moscow Jan 07 '15 at 10:23
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/68331/discussion-between-stack-and-vlad-from-moscow). – Stack Jan 07 '15 at 10:41
0
bool compare(struct Stack* stack,struct Node* head) {
    struct Node* temp=head;//<- Needs initialising. It wasn't.
    struct Node* curr=head;
    while(temp) {
        push(stack,temp->data);
        temp=temp->next;
    }
    while(curr) {
        if(pop(stack)==curr->data) {
           curr=curr->next;
        } else {
            //exit(0); <--Some mistake surely!
            return false; //Slightly less drastic!
        }
    }
    return true;
}

It's slightly a matter of taste but I find long series of variable declarations to be difficult to read and hence error-prone.

You only really need one local variable - but your compiler probably optimizes that away.

exit(0) will abruptly end the program. Most likely indicates 'success' (the exit of 0).

You should return false;.

PS: Credit for using #include <stdbool.h>.

Persixty
  • 8,165
  • 2
  • 13
  • 35