c - 如何在新的单链表中返回单链表的奇数索引节点?假设第一个节点的索引为 1
问题描述
当我运行此代码时,我没有从编译器收到错误消息,但我无法返回新列表。我在 MAIN 部分写错了代码吗?
输入
10->20->30->40->50->60->70->80->90->100
输出必须是
10->30->50->70->90
#include <stdio.h>
#include <stdlib.h>
typedef struct SinglyLinkedListItem
{
int data;
struct SinglyLinkedListItem*next;
}SLLI;
SLLI*OddNodes(SLLI*pHead)
{
int counter =1;
SLLI*pTemp=pHead;
SLLI*pList=NULL;
while(pTemp != NULL)
{
if(counter % 2 != 0)
{
if(pList==NULL)
{
pList=malloc(sizeof(SLLI));
pList->data=pTemp->data;
pList->next=NULL;
}
else
{
SLLI*pIter=pList;
SLLI*pNew=malloc(sizeof(SLLI));
pNew->data=pTemp->data;
pNew->next=NULL;
pIter->next=pNew;
pIter=pIter->next;
}
}
pTemp=pTemp->next;
counter ++;
}
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;
}
函数输出为
10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70 -> 80 -> 90 -> 100 -> null
20 -> 40 -> 60 -> 80 -> 100 -> null
10 -> 30 -> 50 -> 70 -> 90 -> null
如果您不打算更改原始列表,那么函数看起来会更简单,因为在这种情况下,不需要通过引用将指针 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;
}
它的输出是
10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70 -> 80 -> 90 -> 100 -> null
10 -> 20 -> 30 -> 40 -> 50 -> 60 -> 70 -> 80 -> 90 -> 100 -> null
10 -> 30 -> 50 -> 70 -> 90 -> null
如果您不了解通过引用使用指针的工作,那么该函数可以如下所示
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;
}
推荐阅读
- macos - NSCollectionView,与组合布局左对齐
- php - 需要一个 wp all export 函数来反序列化特定字段的数据
- nestjs - 如何返回新创建的实体及其与 Nest.js/TypeORM 的关系?
- ios - 使用存储在参数中的类型转换对象
- c++ - C++ 和 CLion - 特定于平台的代码有问题
- javascript - 带有 Vue 路由器的 Vue 3:路由器链接具有正确的 Vue 参数,但未反映在 HTML 中
- java - 在 Java 中删除包含单元格“NULL”的 csv 格式的行
- python - 根据其他列中的值限制多个数据框列
- c++ - 未解析的外部符号 __tzname Perforce 库
- ssas - 以下哪个 MDX 语法最“正确”?