C 如果双链接列表为奇数,则删除中间和最后一个节点

C 如果双链接列表为奇数,则删除中间和最后一个节点,c,struct,linked-list,doubly-linked-list,function-definition,C,Struct,Linked List,Doubly Linked List,Function Definition,我有一项任务要做。。任务是只删除双链表中第一次出现的奇数值,并且我必须考虑所有特殊情况,例如:如果奇数@开始、中间或最后。到目前为止,我的代码运行得很好,我检查了它,它只删除了前面的代码(如果是奇数),但在其他情况下,例如删除最后一个/中间的代码。。我无法为他们获得输出。基本上,运行的命令没有显示任何内容:( 我的代码很好,我检查过了,删除了前面的代码 只有 你错了。这个代码片段 else if (temp == *front) { //if odd num founded @ the begi

我有一项任务要做。。任务是只删除双链表中第一次出现的奇数值,并且我必须考虑所有特殊情况,例如:如果奇数@开始、中间或最后。到目前为止,我的代码运行得很好,我检查了它,它只删除了前面的代码(如果是奇数),但在其他情况下,例如删除最后一个/中间的代码。。我无法为他们获得输出。基本上,运行的命令没有显示任何内容:(

我的代码很好,我检查过了,删除了前面的代码 只有

你错了。这个代码片段

else if (temp == *front) { //if odd num founded @ the begining of the doubly linked list!
    oddnum = (*front)->data;
    *front = (*front)->next;
    (*front)->previous = NULL;
    free(temp);
}
当列表仅包含一个节点时,无法调用未定义的行为,因为在此语句之后

    *front = (*front)->next;
    (*front)->previous = NULL;
指针
front
将等于NULL,您不能在下面的语句中使用此NULL指针

    *front = (*front)->next;
    (*front)->previous = NULL;
该函数可以用以下方式定义:如果在返回存储值时找到具有奇数值的节点,则返回-1

int DeleteFirstODD( Node **front ) 
{
    int oddnum = -1;

    Node *temp = *front;

    while ( temp != NULL && temp->data % 2 == 0 )
    {
        temp = temp->next;
    }

    if ( temp != NULL )
    {
        oddnum = temp->data;
        
        if ( temp == *front ) 
        { 
            if ( temp->next != NULL )
            {
                temp->next->previous = temp->previous;
            }
            *front = temp->next;
        }
        else if ( temp->next == NULL ) 
        { 
            temp->previous->next = temp->next;
        }
        else 
        {
            temp->previous->next = temp->next;
            temp->next->previous = temp->previous;
        }

        free( temp );
    }

    return oddnum;
}
这是一个演示程序

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

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

int push_front( Node **head, int data )
{
    Node *new_node = malloc( sizeof( Node ) );
    int success = new_node != NULL;
    
    if ( success )
    {
        new_node->data     = data;
        new_node->next     = *head;
        if ( *head ) ( *head )->previous = new_node;
        new_node->previous = NULL; 
        
        *head = new_node;
    }
    
    return success;
}

void display( const Node *head )
{
    for ( ; head; head= head->next )
    {
        printf( "%d -> ", head->data );
    }
    puts( "null" );
}

int DeleteFirstODD( Node **front ) 
{
    int oddnum = -1;

    Node *temp = *front;

    while ( temp != NULL && temp->data % 2 == 0 )
    {
        temp = temp->next;
    }

    if ( temp != NULL )
    {
        oddnum = temp->data;
        
        if ( temp == *front ) 
        { 
            if ( temp->next != NULL )
            {
                temp->next->previous = temp->previous;
            }
            *front = temp->next;
        }
        else if ( temp->next == NULL ) 
        {
            temp->previous->next = temp->next;
        }
        else 
        {
            temp->previous->next = temp->next;
            temp->next->previous = temp->previous;
        }

        free( temp );
    }

    return oddnum;
}

int main(void) 
{
    Node *head = NULL;
    const int N = 10;
    
    for ( int i = N; i != 0; i-- )
    {
        push_front( &head, i );
    }
    
    display( head );

    for ( int num; ( num = DeleteFirstODD( &head ) ) != -1; )
    {
        printf( "The value of the deleted node is %d\n", num );
        display( head );
    }
    
    return 0;
}

当您发现代码不适用于这些情况时,您做了什么?然后您是否继续调试它?在调试器中运行您的程序并逐行检查它运行时的状态。对于第一种情况(当第一个节点=1时)但当我测试另外两种情况时,程序会在删除前打印列表,我想在删除前和删除后打印列表,这样我就能看到它们之间的区别。我明白。但是测试和调试不一样。只需在删除前和删除后打印列表是一个很好的第一步,但调试的过程要多得多至少可以完成。调试意味着将问题追溯到每一行代码和变量值的每一次更改,以了解问题所在。我在多个程序中尝试了您的代码,在上一个else语句中,它无法按预期工作,我尝试调试代码。我们的两个代码都有相同的问题:(我仍然不知道这是否是工作异常的编译器。@it'sM查看演示程序。@it'sM您似乎在使用我先前回答您的类似问题时使用的函数push_front,该问题有一个遗漏语句。:)