使用C中的双指针插入到链接列表中

时间:2016-04-11 16:23:50

标签: c algorithm linked-list

void insert(list **l, int x)
{
       list *p;
       p = malloc(sizeof(list));
       p->item = x;
       p->next = *l;
       *l=p;
}

为什么我们使用双指针?我们可以使用单指针做同样的事情吗?我在“算法设计手册”第69页第2版中看到了这个例子。

列表基本上是节点,仅供参考。

5 个答案:

答案 0 :(得分:2)

  

我们可以使用单指针做同样的事情吗?

您可以使用带有次要更新的单个指针完成此操作。

返回已分配的指针,并确保正确更改了函数调用。

list* insert(list *l, int x)
{
   // list = *p
   // What was that? That is not valid code.

   list* p = malloc(sizeof(list));
   p->item = x;
   p->next = l;
   return p;
}

并将其用作

list* l = NULL;
l = insert(l, 10);

答案 1 :(得分:1)

在这里使用双指针是合理的,因为在函数中,您在列表的头部插入节点,因此变量l将使用新的标题*l=p;

进行更改
*l->|node1|->|node2| //initial value
p->|nodeP| //after p = malloc(sizeof(list)); p->item = x;
p->|nodeP|->|node1|->|node2| //p->next = *l;
*l->|nodeP|->|node1|->|node2| //after *l=p

在这种情况下,函数被调用如下:

list *head;
insert(&head, 4);

对于你的问题:

  

我们可以使用单指针完成同样的事情吗?

是的,该功能将如下所示:

list *insert(list *l, int x)
{
       list *p;
       p = malloc(sizeof(list));
       p->item = x;
       p->next = l;
       return p;
}

你可以在这种情况下调用函数:

list *head;
head = insert(head, 4);

答案 2 :(得分:1)

C中的参数按值传递。因此,为了对函数中的变量进行一些更改,我们必须告诉该函数变量的地址。这使它能够通过将数据写入相应的内存来更改变量间接的值。

因此,要修改int,您必须传递int *。在您的情况下,要修改list *p->next的类型),您必须传递list **

答案 3 :(得分:0)

Basically u might be calling the insert function using insert(&head,x);
Previously head would have stored the address of your first node in the
linked list and u give the address of the head node to l and to access the
address of a u need to dereference it once and to change its value u need to 
dereference it twice.

and obviously u can do it without double pointers just giving the value of   
head to l  insert(head,x)....and in the function declaring insert(int *l,int 
x) 
suppose

address of a(first node)=123

value of head=123

address of head =456

l(storing address of head)=456

In order to get the address of the first node dereference once

*l=123
in order to change value or to go to the next node you dereference it twice
for visual satisfaction have a look at the diagram image i tried to figure
out for your better understanding.


----------

[这里有一个图表,可以让你清楚地了解双指针的方式    在这里工作] [1]     [1]:http://i.stack.imgur.com/HQOaa.jpg

答案 4 :(得分:0)

在此示例中,您需要使用双指针,因为您还希望更改列表的起始节点。因此,基本上当您插入新元素时,您还希望将包含它的节点作为列表中的第一个。如果只传递一个指针(list *l)并为其分配新创建的节点(p),则更改(并且通过更改我的意思是它将是第一个节点list)只能在你的函数中使用,并且不会在它之外传播。

为了更清楚,如果您使用简单的指针(list *l),您基本上会复制list*变量所存储的地址。坐在你的函数之外,在新创建的指针(l参数)中。因此,函数内的l变量是一个不同的指针(内存中与函数外部的指针变量不同的位置),包含与函数外部指针相同的地址。因此,将新创建的元素分配给此l单指针的原因只会使新插入的元素成为第一个本地(函数范围)。

与你使用双指针(所以list **l)时的替代方法相比,真正发生的是通过将外部指针变量传递给函数,你实际上已经通过外部指针的地址,不要与指针所包含的地址混淆。 (注意,因为你必须调用这样的函数:insert(&l, 2))。这样,通过解除引用并将其用作rvalue(p->next = *l)并同时使用外部变量的地址,您仍将拥有外部指针所包含的地址,因此当您进行制作时*l = p(注意*l在这里被用作左值),你实际上是取消引用双指针,结果你将获得真实变量的地址(外部变量),分配给它是新创建的节点。换句话说,您实际上是将新创建的节点设置为起始节点,但这次也在函数之外。

真的希望这不是非常混乱。