对于链表的操作如何正确使用二级指针和一级指针

首先可能大家有以下疑惑:

为什么在链表的删除或者插入的操作中要用二级指针?

为什么无头节点的单链表尾插必须使用二级指针,而带头节点的可以不用?

这也是我曾经疑惑的问题,但是当我看到下面这段话的时候心里几个大字飘过“原来如此”

用C语言描述一个单链表如下:

typedef int DataType;
typedef struct LinkList
{
    struct LinkList* next;
    DataType data;
}Node,*List;
Node *p;//p是节点
List head;//head是头指针

从上面的定义来看p和head实际上是同一类型的变量,都是LinkList类型的指针.
因为插入和删除操作有时需要改变实参的指针(比如头节点为空的时候插入节点,这就是修改了头节点),那么就必须将相应的形参说明为指针的指针(也就是二级指针,因为如果是一级指针,当改变形参的指针时,实参的指针并不发生改变),当函数调用时将实参指针的地址传递给相应的实参。
例如:当刚才的头节点head为空时,要插入一个节点,如果调用的函数形参为一级指针(LinkList* p),其实p为head的一份临时拷贝,改变p并不能改变head.但是调用的函数形参为二级指针(LinkList** p),这样p = &head(p=head的地址), 在函数中 *p = head(对p进行解引用就和head指向同一空间)所以对p的修改就是对head的修改。

不知道我说的大家能理解吗?

还有请大家记住:

没有头节点的单链表如果要改变头指针的指向都要传二级指针,
带头节点的单链表只有销毁和初始化才需要传二级指针,

当然用二级指针也可以实现一级指针的功能(也就是说传一级指针的函数都可以用二级指针代替,但是有一定的风险,毕竟二级指针可以对链表头节点进行直接修改)
还有希望大家知道:传二级指针就是在从链表头指针开始对链表操作,传一级指针只不过是对头结点head生成了一个拷贝p,p的next指向的仍然是head的next,因此,后面的操作仍然是在原链表上操作。

猜你喜欢

转载自blog.csdn.net/qq_39032310/article/details/81746742