此函数 returns 一个列表,其中包含出现在列表 "A" 中 "pos_list" 中给定位置的值
This function returns a list that contains the values that appear in list "A" at positions given in "pos_list"
-如果A列表有整数数据如:1->2->3->4->5->6
- 而pos_list有整数数据如:4->0->5
-那么这个函数应该 return 一个新列表帽子包含出现在列表 A 中 pos_list 中给定位置的值
这样 New List= 5->1->6
我正在实施深度复制以制作新列表。
我正在尝试使用根据 pos_list 的数据进行迭代的循环。在这个循环中,A 的节点将移动到 pos_list 数据的位置。这次我将复制新列表中的节点 A 以制作另一个列表。
对于第一种情况,pos_list 有数据 4,因此循环将 运行 4 次,直到列表 A 的节点指向它的第四个位置。在这个循环中,我将在一个新循环中复制列表 A 的数据。
我需要指导来解决这个问题。
struct node * sublist(struct node * A, struct node * pos_list) {
struct node* newList=NULL;
struct node * curr;
int i=0;
for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data.
struct node* newList = (struct node *) malloc(sizeof (struct node));
for(int i=0;i<=pos_list->data;i++){ //counter for pos_list as it will be (3 then 0,6 and 4)
if(i==pos_list->data){ //At the time when i == pos_list->data(3 or 0 or 6..)
newList->data = A->data; //Putting value of list A data in new list.
newList = newList->next; //Linking
printf("%d\t", newList->data); //Just for log
}
A=A->next; //Going to next position on A
}
pos_list=pos_list->next; //Going to next position on B
}
return newList ;
}
如果列表是:1->2->3->4->5->6
而pos_list是:4->0->5
我希望输出是新列表 5->1->6
您的代码有几个问题:
- 您应该从
pos_list
开始遍历,而不是 pos_list->next
。头指针指向的节点是列表的一部分。此外,如果 pos_list == NULL
,pos_list->next
将导致未定义的行为。
int i
的外部定义没有用。删除它。
- 不要通过位置遍历
A
。如果该位置无效,您将越过列表末尾,获取空指针并调用未定义的行为。列表应该由从先前节点的 next
指针访问的列表节点迭代。 (当然,提供有效位置是调用者的责任,但您的程序应该优雅地处理无效输入。)
- 只有在找到有效位置后才创建新节点。否则你会创建一个永远不会插入的节点,从而导致内存泄漏。
- 此处:
newList = newList->next
、newList->next
未初始化。请记住,malloc
为您提供了一大块未初始化的数据。
- 您尝试使
newList
指向新创建列表的末尾,以便快速添加新节点。这是个好主意,但如果您 return 该指针,您将得到一个仅包含一个元素的列表。 (您也将没有登录者能够访问该列表中任何先前创建的节点。)
这是一个应该有效的实现:
struct node *sublist(struct node *A, struct node *pos_list)
{
struct node *newHead = NULL;
struct node *newTail = NULL;
struct node *pos = pos_list;
while (pos) {
struct node *a = A;
int i = 0;
while (a) {
if (i == pos->data) {
struct node *node = malloc(sizeof(*node));
if (newHead == NULL) newHead = node;
if (newTail) newTail->next = node;
node->data = a->data;
node->next = NULL;
newTail = node;
break;
}
a = a->next;
i++;
}
pos = pos->next;
}
return newHead;
}
问题不允许使用 "struct" 来实现解决方案。
如果是,我错了,但如果不是,这不是矫枉过正,当类似于以下的东西可以实现时....
#include <stdio.h>
#define CREATE_ARRAY(n) int result[n]
void main() {
int data[] = {1,2,3,4,5,6};
int pos[] = {4,0,5};
int i;
CREATE_ARRAY(sizeof(pos)/sizeof(int));
for(i = 0; i < sizeof(pos)/sizeof(int);++i)
result[i] = data[pos[i]];
/*
To print the values stored in result
for(i = 0;i < sizeof(result)/sizeof(int); ++i)
printf("%d ",result[i]);
putchar('\n');
}
*/
对于初学者来说,函数 sublist
应该声明为
struct node * sublist( const struct node *A, const struct node *pos_list );
因为列表A
和列表pos_list
在函数中都没有改变。否则函数的声明会使代码的读者感到困惑。
列表 pos_list
包含虚拟节点是个坏主意,因为它写在对此声明的评论中
for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data
虚拟节点都不应该在列表中。
在这个内循环中
for(int i=0;i<=pos_list->data;i++){
没有使用列表的虚拟节点。此外pos_list在两个循环中遍历:外循环和内循环
for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data.
struct node* newList = (struct node *) malloc(sizeof (struct node));
for(int i=0;i<=pos_list->data;i++){
在循环中,变量 newList
的值已更改
newList = newList->next;
因此函数总是 returns 一些不确定的值而不是新创建列表的头部。该值是不确定的,因为新创建的节点的数据成员next没有被初始化。
newList->data = A->data; //Putting value of list A data in new list.
newList = newList->next;
函数可以这样定义
struct node * sublist( const struct node *A, const struct node *pos_list )
{
struct node *newList = NULL;
struct node **current = &newList;
for ( ; pos_list != NULL; pos_list = pos_list->next )
{
const struct node *target = A;
for ( int index = pos_list->data; index != 0 && target != NULL; --index )
{
target = target->next;
}
if ( target != NULL )
{
*current = malloc( sizeof( struct node ) );
( *current )->data = target->data;
( *current )->next = NULL;
current = &( *current )->next;
}
}
return newList;
}
-如果A列表有整数数据如:1->2->3->4->5->6 - 而pos_list有整数数据如:4->0->5 -那么这个函数应该 return 一个新列表帽子包含出现在列表 A 中 pos_list 中给定位置的值 这样 New List= 5->1->6
我正在实施深度复制以制作新列表。 我正在尝试使用根据 pos_list 的数据进行迭代的循环。在这个循环中,A 的节点将移动到 pos_list 数据的位置。这次我将复制新列表中的节点 A 以制作另一个列表。 对于第一种情况,pos_list 有数据 4,因此循环将 运行 4 次,直到列表 A 的节点指向它的第四个位置。在这个循环中,我将在一个新循环中复制列表 A 的数据。 我需要指导来解决这个问题。
struct node * sublist(struct node * A, struct node * pos_list) {
struct node* newList=NULL;
struct node * curr;
int i=0;
for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data.
struct node* newList = (struct node *) malloc(sizeof (struct node));
for(int i=0;i<=pos_list->data;i++){ //counter for pos_list as it will be (3 then 0,6 and 4)
if(i==pos_list->data){ //At the time when i == pos_list->data(3 or 0 or 6..)
newList->data = A->data; //Putting value of list A data in new list.
newList = newList->next; //Linking
printf("%d\t", newList->data); //Just for log
}
A=A->next; //Going to next position on A
}
pos_list=pos_list->next; //Going to next position on B
}
return newList ;
}
如果列表是:1->2->3->4->5->6 而pos_list是:4->0->5
我希望输出是新列表 5->1->6
您的代码有几个问题:
- 您应该从
pos_list
开始遍历,而不是pos_list->next
。头指针指向的节点是列表的一部分。此外,如果pos_list == NULL
,pos_list->next
将导致未定义的行为。 int i
的外部定义没有用。删除它。- 不要通过位置遍历
A
。如果该位置无效,您将越过列表末尾,获取空指针并调用未定义的行为。列表应该由从先前节点的next
指针访问的列表节点迭代。 (当然,提供有效位置是调用者的责任,但您的程序应该优雅地处理无效输入。) - 只有在找到有效位置后才创建新节点。否则你会创建一个永远不会插入的节点,从而导致内存泄漏。
- 此处:
newList = newList->next
、newList->next
未初始化。请记住,malloc
为您提供了一大块未初始化的数据。 - 您尝试使
newList
指向新创建列表的末尾,以便快速添加新节点。这是个好主意,但如果您 return 该指针,您将得到一个仅包含一个元素的列表。 (您也将没有登录者能够访问该列表中任何先前创建的节点。)
这是一个应该有效的实现:
struct node *sublist(struct node *A, struct node *pos_list)
{
struct node *newHead = NULL;
struct node *newTail = NULL;
struct node *pos = pos_list;
while (pos) {
struct node *a = A;
int i = 0;
while (a) {
if (i == pos->data) {
struct node *node = malloc(sizeof(*node));
if (newHead == NULL) newHead = node;
if (newTail) newTail->next = node;
node->data = a->data;
node->next = NULL;
newTail = node;
break;
}
a = a->next;
i++;
}
pos = pos->next;
}
return newHead;
}
问题不允许使用 "struct" 来实现解决方案。 如果是,我错了,但如果不是,这不是矫枉过正,当类似于以下的东西可以实现时....
#include <stdio.h>
#define CREATE_ARRAY(n) int result[n]
void main() {
int data[] = {1,2,3,4,5,6};
int pos[] = {4,0,5};
int i;
CREATE_ARRAY(sizeof(pos)/sizeof(int));
for(i = 0; i < sizeof(pos)/sizeof(int);++i)
result[i] = data[pos[i]];
/*
To print the values stored in result
for(i = 0;i < sizeof(result)/sizeof(int); ++i)
printf("%d ",result[i]);
putchar('\n');
}
*/
对于初学者来说,函数 sublist
应该声明为
struct node * sublist( const struct node *A, const struct node *pos_list );
因为列表A
和列表pos_list
在函数中都没有改变。否则函数的声明会使代码的读者感到困惑。
列表 pos_list
包含虚拟节点是个坏主意,因为它写在对此声明的评论中
for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data
虚拟节点都不应该在列表中。
在这个内循环中
for(int i=0;i<=pos_list->data;i++){
没有使用列表的虚拟节点。此外pos_list在两个循环中遍历:外循环和内循环
for (i = 0, curr = pos_list->next; (curr != NULL); curr = curr->next) { //pos_list->data has a dummy node so loop until the end of pos_list->data.
struct node* newList = (struct node *) malloc(sizeof (struct node));
for(int i=0;i<=pos_list->data;i++){
在循环中,变量 newList
的值已更改
newList = newList->next;
因此函数总是 returns 一些不确定的值而不是新创建列表的头部。该值是不确定的,因为新创建的节点的数据成员next没有被初始化。
newList->data = A->data; //Putting value of list A data in new list.
newList = newList->next;
函数可以这样定义
struct node * sublist( const struct node *A, const struct node *pos_list )
{
struct node *newList = NULL;
struct node **current = &newList;
for ( ; pos_list != NULL; pos_list = pos_list->next )
{
const struct node *target = A;
for ( int index = pos_list->data; index != 0 && target != NULL; --index )
{
target = target->next;
}
if ( target != NULL )
{
*current = malloc( sizeof( struct node ) );
( *current )->data = target->data;
( *current )->next = NULL;
current = &( *current )->next;
}
}
return newList;
}