Palindrome LinkedList

时间:2015-01-07 08:09:35

标签: c

方法:

  1. 从头到尾遍历给定列表,并将每个访问过的节点推送到堆栈。

  2. 再次遍历列表。对于每个被访问节点,从堆栈弹出一个节点,并将弹出节点的数据与当前访问的节点进行比较。

  3. 如果所有节点都匹配,则返回true,否则返回false。

  4. 编辑:程序编译时没有错误,但在运行时停止工作

    #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;
    }
    

4 个答案:

答案 0 :(得分:2)

struct Node* temp;

temp未在

中初始化
bool compare(struct Stack* stack,struct Node* head)

struct Node* temp,* curr=head;

不是

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

使用未初始化的变量会导致未定义的行为。

答案 1 :(得分:2)

您已获得未初始化的本地变量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;
} 

你需要先修复它;我认为以下内容应该有效:

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;
} 

接下来,您将使用"%s"打印布尔结果,该结果用于字符串。您需要执行以下操作:

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

或者

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

此时,它不再为我崩溃,并适用于几个简单的测试用例。您可能会考虑如何处理堆栈溢出的情况,并考虑格式化代码以使其更具可读性。

答案 2 :(得分:2)

函数compare至少有两个错误。第一个是它使用未初始化的指针temp

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

第二个是函数永远不会返回false,但根据赋值,如果列表和堆栈中的值不匹配,它必须返回false。 而不是返回false,而是调用函数exit

else
exit(0);

我会按照以下方式编写函数

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 );
} 

唯一正确的函数实现在其他答案中提供的函数实现中。:)

由于C没有类型bool,那么你可以在用C编写的程序中使用名称bool,你必须包含头<stdbool.h>或者自己定义这个名字作为_Bool的typedef(如果你的编译器支持这个type)或int。

如果您不想包含标题<stdbool.h>,则可以将函数的返回类型声明为int。例如

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

考虑到您还需要编写将为列表和堆栈释放所有已分配内存的函数。

例如,您可以通过以下方式释放为堆栈分配的内存

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

    *stack = NULL;
}

以同样的方式释放为列表分配的内存

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;
}  

答案 3 :(得分: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;
}

这只是一个品味问题,但我发现很长一系列的变量声明难以阅读,因而容易出错。

您只需要一个局部变量 - 但您的编译器可能会优化它。

exit(0)将突然结束该计划。最有可能表示“成功”(退出0)。

你应该return false;

PS:使用#include <stdbool.h>的信用。