C 如何在新的单链表中返回单链表的奇数索引节点?假设第一个节点的索引为1

C 如何在新的单链表中返回单链表的奇数索引节点?假设第一个节点的索引为1,c,algorithm,data-structures,structure,singly-linked-list,C,Algorithm,Data Structures,Structure,Singly Linked List,当我运行这段代码时,我没有收到来自编译器的错误消息,但我无法返回新列表。我在主体部分写错代码了吗 输入 输出必须是 10->30->50->70->90 #包括 #包括 typedef结构SingleyLinkedListItem { int数据; 结构SinglyLinkedListItem*next; }SLLI; SLLI*ODDDNodes(SLLI*pHead) { int计数器=1; SLLI*pTemp=pHead; SLLI*pList=NULL; wh

当我运行这段代码时,我没有收到来自编译器的错误消息,但我无法返回新列表。我在主体部分写错代码了吗

输入

输出必须是

10->30->50->70->90
#包括
#包括
typedef结构SingleyLinkedListItem
{
int数据;
结构SinglyLinkedListItem*next;
}SLLI;
SLLI*ODDDNodes(SLLI*pHead)
{
int计数器=1;
SLLI*pTemp=pHead;
SLLI*pList=NULL;
while(pTemp!=NULL)
{
如果(计数器%2!=0)
{
if(pList==NULL)
{
pList=malloc(sizeof(SLLI));
pList->data=pTemp->data;
pList->next=NULL;
}
其他的
{
SLLI*pIter=pList;
SLLI*pNew=malloc(sizeof(SLLI));
pNew->data=pTemp->data;
pNew->next=NULL;
pIter->next=pNew;
pIter=pIter->next;
}
}
pTemp=pTemp->next;
计数器++;
}
返回层;
}

您总是在更改同一对象
pList->next

       else
       {
           pList->next=pTemp;
       }
而且原来的名单没有改变。因此,函数具有未定义的行为

对于初学者,应该通过引用传递原始节点的头部。否则,该函数将处理head的副本,副本的任何更改都不会影响原始列表

下面是一个演示程序,演示如何实现该功能

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

typedef struct SinglyLinkedListItem
{
    int data;
    struct SinglyLinkedListItem *next;
} SLLI;

SLLI * OddNodes( SLLI **pHead )
{
    int odd = 0;
    SLLI *pList = NULL;
    SLLI **pCurrent = &pList;

    while ( *pHead != NULL )
    {
        if ( odd ^= 1 )
        {
            *pCurrent = *pHead;
            *pHead = ( *pHead )->next;
            ( *pCurrent )->next = NULL;
            pCurrent = &( *pCurrent )->next;
        }
        else
        {
            pHead = &( *pHead )->next;
        }
    }

    return pList;
 }

 int insert( SLLI **pHead, int data )
 {
    SLLI *pCurrent = malloc( sizeof( SLLI ) );
    int success = pCurrent != NULL;

    if ( success )
    {
        pCurrent->data = data;
        pCurrent->next = *pHead;
        *pHead = pCurrent;
    }

    return success;
 }

 void out( SLLI *pHead )
 {
    for ( ; pHead != NULL; pHead = pHead->next )
    {
        printf( "%d -> ", pHead->data );
    }

    puts( "null" );
 }

int main(void) 
{
    const int N = 10;

    SLLI *pHead = NULL;

    for ( int i = N; i != 0; --i )
    {
        insert( &pHead, 10 * i );
    }

    out( pHead );

    SLLI *pSecondHead = OddNodes( &pHead );

    out( pHead );
    out( pSecondHead );

    return 0;
}
如果您不打算更改原始列表,那么函数看起来会更简单,因为在这种情况下,不需要通过引用将指针pHead传递给函数

这是一个演示程序

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

typedef struct SinglyLinkedListItem
{
    int data;
    struct SinglyLinkedListItem *next;
} SLLI;

SLLI * OddNodes( SLLI *pHead )
{
    int odd = 0;
    SLLI *pList = NULL;
    SLLI **pCurrent = &pList;

    for ( ; pHead != NULL; pHead = pHead->next )
    {
        if ( odd ^= 1 )
        {
            *pCurrent = malloc( sizeof( SLLI ) );
            ( *pCurrent )->data = pHead->data;
            ( *pCurrent )->next = NULL;
            pCurrent = &( *pCurrent )->next;
        }
    }

    return pList;
 }

 int insert( SLLI **pHead, int data )
 {
    SLLI *pCurrent = malloc( sizeof( SLLI ) );
    int success = pCurrent != NULL;

    if ( success )
    {
        pCurrent->data = data;
        pCurrent->next = *pHead;
        *pHead = pCurrent;
    }

    return success;
 }

 void out( SLLI *pHead )
 {
    for ( ; pHead != NULL; pHead = pHead->next )
    {
        printf( "%d -> ", pHead->data );
    }

    puts( "null" );
 }

int main(void) 
{
    const int N = 10;

    SLLI *pHead = NULL;

    for ( int i = N; i != 0; --i )
    {
        insert( &pHead, 10 * i );
    }

    out( pHead );

    SLLI *pSecondHead = OddNodes( pHead );

    out( pHead );
    out( pSecondHead );

    return 0;
}
如果您不理解通过引用使用指针的工作,那么函数可以按照以下方式查看

SLLI * OddNodes( SLLI *pHead )
{
    int odd = 0;
    SLLI *pList = NULL;


    for ( SLLI *pCurrent = pList; pHead != NULL; pHead = pHead->next )
    {
        if ( odd ^= 1 )
        {
            if ( pCurrent == NULL )
            {
                pList = malloc( sizeof( SLLI ) );
                pList->data = pHead->data;
                pList->next = NULL;
                pCurrent = pList;
            }
            else
            {
                pCurrent->next = malloc( sizeof( SLLI ) );
                pCurrent->next->data = pHead->data;
                pCurrent->next->next = NULL;
                pCurrent = pCurrent->next;
            }
        }
    }

    return pList;
}

您总是在更改同一对象
pList->next

       else
       {
           pList->next=pTemp;
       }
而且原来的名单没有改变。因此,函数具有未定义的行为

对于初学者,应该通过引用传递原始节点的头部。否则,该函数将处理head的副本,副本的任何更改都不会影响原始列表

下面是一个演示程序,演示如何实现该功能

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

typedef struct SinglyLinkedListItem
{
    int data;
    struct SinglyLinkedListItem *next;
} SLLI;

SLLI * OddNodes( SLLI **pHead )
{
    int odd = 0;
    SLLI *pList = NULL;
    SLLI **pCurrent = &pList;

    while ( *pHead != NULL )
    {
        if ( odd ^= 1 )
        {
            *pCurrent = *pHead;
            *pHead = ( *pHead )->next;
            ( *pCurrent )->next = NULL;
            pCurrent = &( *pCurrent )->next;
        }
        else
        {
            pHead = &( *pHead )->next;
        }
    }

    return pList;
 }

 int insert( SLLI **pHead, int data )
 {
    SLLI *pCurrent = malloc( sizeof( SLLI ) );
    int success = pCurrent != NULL;

    if ( success )
    {
        pCurrent->data = data;
        pCurrent->next = *pHead;
        *pHead = pCurrent;
    }

    return success;
 }

 void out( SLLI *pHead )
 {
    for ( ; pHead != NULL; pHead = pHead->next )
    {
        printf( "%d -> ", pHead->data );
    }

    puts( "null" );
 }

int main(void) 
{
    const int N = 10;

    SLLI *pHead = NULL;

    for ( int i = N; i != 0; --i )
    {
        insert( &pHead, 10 * i );
    }

    out( pHead );

    SLLI *pSecondHead = OddNodes( &pHead );

    out( pHead );
    out( pSecondHead );

    return 0;
}
如果您不打算更改原始列表,那么函数看起来会更简单,因为在这种情况下,不需要通过引用将指针pHead传递给函数

这是一个演示程序

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

typedef struct SinglyLinkedListItem
{
    int data;
    struct SinglyLinkedListItem *next;
} SLLI;

SLLI * OddNodes( SLLI *pHead )
{
    int odd = 0;
    SLLI *pList = NULL;
    SLLI **pCurrent = &pList;

    for ( ; pHead != NULL; pHead = pHead->next )
    {
        if ( odd ^= 1 )
        {
            *pCurrent = malloc( sizeof( SLLI ) );
            ( *pCurrent )->data = pHead->data;
            ( *pCurrent )->next = NULL;
            pCurrent = &( *pCurrent )->next;
        }
    }

    return pList;
 }

 int insert( SLLI **pHead, int data )
 {
    SLLI *pCurrent = malloc( sizeof( SLLI ) );
    int success = pCurrent != NULL;

    if ( success )
    {
        pCurrent->data = data;
        pCurrent->next = *pHead;
        *pHead = pCurrent;
    }

    return success;
 }

 void out( SLLI *pHead )
 {
    for ( ; pHead != NULL; pHead = pHead->next )
    {
        printf( "%d -> ", pHead->data );
    }

    puts( "null" );
 }

int main(void) 
{
    const int N = 10;

    SLLI *pHead = NULL;

    for ( int i = N; i != 0; --i )
    {
        insert( &pHead, 10 * i );
    }

    out( pHead );

    SLLI *pSecondHead = OddNodes( pHead );

    out( pHead );
    out( pSecondHead );

    return 0;
}
如果您不理解通过引用使用指针的工作,那么函数可以按照以下方式查看

SLLI * OddNodes( SLLI *pHead )
{
    int odd = 0;
    SLLI *pList = NULL;


    for ( SLLI *pCurrent = pList; pHead != NULL; pHead = pHead->next )
    {
        if ( odd ^= 1 )
        {
            if ( pCurrent == NULL )
            {
                pList = malloc( sizeof( SLLI ) );
                pList->data = pHead->data;
                pList->next = NULL;
                pCurrent = pList;
            }
            else
            {
                pCurrent->next = malloc( sizeof( SLLI ) );
                pCurrent->next->data = pHead->data;
                pCurrent->next->next = NULL;
                pCurrent = pCurrent->next;
            }
        }
    }

    return pList;
}

你说“我不能退回新名单”是什么意思?运行代码时会发生什么?会发生什么?另外,请花一些时间阅读,以及。另外,请尝试创建一个显示给我们的。另外,在创建新列表时,您还需要为该列表创建新节点。您不能重复使用旧列表中的节点,这将破坏旧列表。@YTE 1008甚至是从源列表中删除并移动到目标列表的节点吗?我对这个平台非常陌生,首先为我的缺点感到抱歉。我不想通过删除索引节点来解决这个问题。我也将尝试它,但不在此代码上。(你所说的“我不能返回新列表”是什么意思?)我的意思是,我不能将输出视为第一、第三、第五,。。。当我运行代码时,新链表上当前链表的节点…你说的“我不能返回新链表”是什么意思?运行代码时会发生什么?会发生什么?另外,请花一些时间阅读,以及。另外,请尝试创建一个显示给我们的。另外,在创建新列表时,您还需要为该列表创建新节点。您不能重复使用旧列表中的节点,这将破坏旧列表。@YTE 1008甚至是从源列表中删除并移动到目标列表的节点吗?我对这个平台非常陌生,首先为我的缺点感到抱歉。我不想通过删除索引节点来解决这个问题。我也将尝试它,但不在此代码上。(你所说的“我不能返回新列表”是什么意思?)我的意思是,我不能将输出视为第一、第三、第五,。。。当我运行代码时,当前链接列表的节点位于新的链接列表上…我确信您编写的代码没有任何简单的错误,但我不容易理解或阅读代码。因为我没有足够的知识什么是SLLI**pHead(我的意思是double**),在这个平台上不可能告诉我,我知道这一点。。。因此,感谢您的帮助…总有一天我会理解这段代码…@YTE1008当您传递的不是原始指针pHead而是指向pHead的指针时,这是一个更高级别的间接寻址。也就是说,您通过引用传递了pHead。因此,您可以在函数中更改pHead。非常感谢@Vlad from的帮助Moscow@YTE1008假设有一个函数void f(int x);当您将一个对象传递给函数f(my_x)时;然后该函数将处理my_x的副本,并且将无法更改原始对象。但是如果你将函数声明为void f(int*px);通过引用传递my_x时,如f(&my_x);然后,该函数可以更改原始对象my_x。但是,如果我不想更改原始链表,只想将奇数索引节点复制到另一个链表并返回此新链表,该怎么办?我确信您编写的代码没有任何简单错误,但我不容易理解或阅读代码。因为我不知道有足够的知识什么是SLLI**pHead(我的意思是双重**)这是不可能告诉我在这个平台上,我知道这。。。因此,感谢您的帮助…总有一天我会理解这段代码…@YTE1008当您传递的不是原始指针pHead而是指向pHead的指针时,这是一个更高级别的间接寻址。那就是你是帕辛