[谁能帮我解决我哪里出错了!!!,我是编程的初学者,我是DSA的新手,我找不到错误,这里的代码请仔细阅读:
这是我的问题的轮廓,希望清楚! :)
sample input : 3 16 13 7 1 2
3 is the number of elements to input into a linked list
so 16 13 7 are elements of the linked list initially
1 is the element I'm interested to insert
2 is the position where I want to insert the element 1
so the expected output will be:
sample output: 16 13 1 7
我面临的问题:
The output I'm getting is: 13 1 7
So the problem is not every element in the list is getting returned, please help !!!
这是我尝试过的代码,鼓励您提出任何建议,:)
struct SinglyLinkedListNode
{
int data;
SinglyLinkedListNode* next;
};
SinglyLinkedListNode* insertNodeAtPosition(SinglyLinkedListNode* head, int data, int position)
{
int i = 0;
SinglyLinkedListNode *pcurr, *pnew;
pnew = (SinglyLinkedListNode*)malloc(sizeof(SinglyLinkedListNode));
if(position == 0)
{
pnew->data = data;
pnew->next = head->next;
head = pnew;
return head;
}
if(head == NULL)
{
pnew ->data = data;
return pnew;
}
else
{
do
{
pcurr = head;
pcurr = pcurr->next;
head = head->next;
i++;
}
while (i != position-1);
pnew->next = pcurr->next;
pnew->data = data;
pcurr->next = pnew;
return head;
}
}
[如果有人建议一个很好的可视化平台来逐行查看我们的代码,尤其是对于c,就像在python中一样,我会很高兴。
有一些问题,代码实际上要简单得多。
您正在执行malloc
两次,而不是仅执行一次,因此您在每次调用时都在浪费内存。
请勿投射malloc:
。请参阅:Do I cast the result of malloc?
SinglyLinkedListNode
有点长。当在很多地方使用时,这种缩放效果不好。像Node
或SlNode
]这样的短代码怎么样?
这里是重构版本:
#include <stdio.h> #include <stdlib.h> typedef struct node Node; struct node { int data; Node *next; }; Node * insertNodeAtPosition(Node *head, int data, int position) { int i = 0; Node *prev; Node *pcurr; Node *pnew; pnew = malloc(sizeof(Node)); pnew->data = data; // find the correct place to insert prev = NULL; for (pcurr = head; pcurr != NULL; pcurr = pcurr->next, i += 1) { if (i >= position) break; prev = pcurr; } // link up the element that will follow the new node pnew->next = pcurr; // insert into middle or end of list if (prev != NULL) prev->next = pnew; // insert into empty list or _before_ the first node else head = pnew; return head; } void printlist(Node *head) { Node *pcurr; printf("List:"); for (pcurr = head; pcurr != NULL; pcurr = pcurr->next) printf(" %d",pcurr->data); printf("\n"); } int main(void) { FILE *fi; Node *head = NULL; int count; int newval; int pos; fi = fopen("input.txt","r"); if (fi == NULL) { perror("input.txt"); exit(1); } fscanf(fi," %d",&count); for (int i = 0; i < count; ++i) { fscanf(fi," %d",&newval); printf("new: %d\n",newval); head = insertNodeAtPosition(head,newval,count + 10); } printlist(head); while (1) { if (fscanf(fi," %d %d",&newval,&pos) != 2) break; printf("insert: %d at %d\n",newval,pos); head = insertNodeAtPosition(head,newval,pos); } printlist(head); fclose(fi); return 0; }
这里是测试文件:
input.txt
:
3 16 13 7 1 2 9 0 8 0
这是程序输出:
new: 16 new: 13 new: 7 List: 16 13 7 insert: 1 at 2 insert: 9 at 0 insert: 8 at 0 List: 8 9 16 13 1 7
UPDATE:
您还可以告诉我为什么我们必须使用指针
*prev
吗?为什么仅pcurr
和pnew
不够?这将有助于我学习作为初学者的新概念。当然。如果由于列表为空而要在列表的开头插入,或者我们想在列表的开头插入(即即使列表中有其他节点,我们也要插入新的标题),请调整
head
。
但是,如果我们要插入列表的中间或追加到列表的末尾,我们需要知道前一个节点是什么。
考虑到我们试图追加到列表的末尾。我们需要知道列表的现有/优先尾部[最后一个元素]。如果我们有:
head | node1 | node2 | node3
然后,
node3
是列表的结尾。node3->next
将为NULL
。要追加,我们创建新节点(pnew
),并且必须设置node3->next = pnew
,所以我们得到:
head | node1 | node2 | node3 | pnew prev
这里,
prev
最终将具有node3
的值,因此设置prev->next = pnew
就像设置node3->next = pnew
。请注意,追加到末尾时,pcurr
将为NULL
。
我们称它为prev
,因为它(前一个节点)也可以是我们想插入之后
prev
位于列表的中间(例如[ C0])。看起来像(before插入):node2
插入后,我们想要:
head | node1 | node2 | node3 prev pcurr
在这种情况下,
head | node1 | node2 | pnew | node3 prev pcurr
将为pcurr
(即node3
)。
因此, followsprev->next
指向我们要插入prev
的节点[pnew
指向我们要插入pcurr
的节点[pnew
是prev
左侧的节点(即preceded的节点)。 pnew
是pcurr
右侧的节点(即pnew
为空,则下一个节点为[[no,但是在[[all情况下,pcurr
或pnew->next = pcurr
的值的不管为空或[没有。如果head
最终为prev
,则表示该列表为空,或者我们希望在列表的开头/开头插入prev
。在这种情况下,我们无法尝试取消引用[null] NULL
,因此我们只需将pnew
设置为prev
。然后,我们返回一个updated head
指针。
列表为空(调整头)
我们要插入新节点之前
[非空]列表的头(调整头)pnew
子句的数量来处理为什么
将在将来极大地帮助您。一个人单独编写的任何一个函数看起来似乎都不多。但是,将其放大到成百上千个功能,它将带来远远超出最初的额外工作所能带来的收益。
一个格言:就像它需要的一样简单,而且没有更简单
代码越简单(即更清晰),它就越有可能是正确的,完整的,并且越容易检查正确性。与流行的看法相反,我还发现,更简单的代码也趋向于更快。head
我希望以上更改能够解决您的问题。我在需要帮助的地方添加了注释,以帮助您理解代码。如果您发现任何错误,请发表评论,我会予以纠正。