我忙着实现单链表,有两个函数:insert_back
和insert_after
。
下面是它们的列表:
void insert_back(int data)
{
node *temp1;
temp1 = (node*)malloc(sizeof(node));
temp1 = head;
while (temp1->next != NULL) {
temp1 = temp1->next;
}
node *temp;
temp = (node*)malloc(sizeof(node));
temp->data = data;
temp->next = NULL;
temp1->next = temp;
}
void insert_after(int pos, int data)
{
node *temp1;
temp1 = (node*)malloc(sizeof(node));
temp1 = head;
for (int i = 1; i < pos; i++) {
temp1 = temp1->next;
if (temp1 == NULL) {
return;
}
}
node *temp;
temp = (node*)malloc(sizeof(node));
temp->data = data;
temp->next = temp1->next;
temp1->next = temp;
}
正如你所看到的,它们几乎是相同的,对于插入,我想写insert_after(null, 10)
。我可以通过添加条件并选择其中一个循环来解决它,但这不是我的目的。
是否有可能以某种方式将一个while
或for
循环一起用于序列号和null?
我还看到参数int pos
是int
。我应该用0代替null吗?
您不必要地在以下行中分配内存。
temp1 = (node*)malloc(sizeof(node));
temp1 = head;
当您覆盖temp1
中返回的地址时,分配的内存将会泄漏。您只需要temp1
遍历列表,因此也不需要分配任何节点本身。temp1
可以指向任意节点
我冒昧地从头开始写一个例程,一次完成这两件事。如果是pos < 0
,它会将元素添加到列表的末尾,否则它会将元素添加到后th元素之后,其中第一个元素对应于pos == 1
。如果pos == 0
,元素被添加到列表的开头。
还添加了一个小main
来测试例程。new_node
已添加到测试是否内存未耗尽
#include <stdlib.h>
#include <stdio.h>
typedef struct node
{
struct node * next;
int data;
} node;
node * head = NULL;
node * new_node(void)
{
node * result = malloc(sizeof(*result));
if (result == NULL)
{
fprintf(stderr, "Out of memory.n");
exit(10);
}
return result;
}
void insert_after(int pos, int data)
{
node *walk, * prev;
int i;
prev = NULL;
walk = head;
for (i = 0; walk != NULL && i != pos; i++)
{
prev = walk;
walk = walk->next;
}
if (i != pos && pos > 0)
{
fprintf(stderr, "Location not found.n");
exit(9);
}
else
{
walk = new_node();
walk->data = data;
if (prev == NULL)
{
walk->next = head;
head = walk;
}
else
{
walk->next = prev->next;
prev->next = walk;
}
}
}
int main(void)
{
int i;
node * wlk;
for (i = 0; i < 10; i++)
{
insert_after(-1, i);
}
for (i = 0; i < 10; i++)
{
insert_after(3, i+10);
}
for (wlk = head; wlk != NULL; wlk = wlk->next)
{
printf("%dn", wlk->data);
}
return 0;
}
由于您正在使用insert_after(pos,…)测试链的末端,因此您可以选择:
void insert_after(int pos, int data)
{
node *temp1= head;
for (int i=1; i<pos; i++) {
if (temp1->next==NULL) {
if (pos==INT_MAX)
break; // pos of INT_MAX means insert at end
// so we continue with this last item and append
else
return; // pos higher than length of chain
}
temp1 = temp1->next;
}
...
}
或者稍微紧凑一点:
void insert_after(int pos, int data)
{
node *temp1= head;
for (int i=1; i<pos && temp1->next!=NULL; i++) {
temp1 = temp1->next;
}
if (temp1->next==NULL && pos!=INT_MAX)
return; // pos higher than length of chain, except for
// INT_MAX (for that we just want to continue)
...
}
那么你可以用
void insert_back(int data)
{
insert_after(INT_MAX, data);
}