单向链表末尾插入一个节点(指向指针的指针该怎样理解)
2018-03-02 21:54
459 查看
程序如下:#include<iostream>
using namespace std;
struct ListNode
{
int value;
ListNode* m_pNext;
};
void AddToTail(ListNode** pHead,int value)
{
ListNode* newNode=new ListNode();
newNode->value=value;
newNode->m_pNext=NULL;
if (pHead==NULL)
{
return;
}
if (*pHead==NULL)
{
*pHead=newNode;
return;
}
ListNode* p=*pHead;
ListNode* q=NULL;
while (p!=NULL)
{
q=p;
p=p->m_pNext;
}
q->m_pNext=newNode;
}
ListNode* CreateLink(int a[],int len)
{
ListNode* Head=NULL,*q=NULL;
for (int i = 0; i < len; i++)
{
ListNode* pNew=new ListNode();
pNew->value=a[i];
pNew->m_pNext=NULL;
if (Head==NULL)
{
Head=pNew;
q=pNew;
}
else
{
q->m_pNext=pNew;
q=pNew;
}
}
return Head;
}
void print(ListNode* head)
{
ListNode* q=head;
while (q!=NULL)
{
cout<<q->value<<endl;
q=q->m_pNext;
}
cout<<endl;
}
int main()
{
int a[]={1,2,3};
ListNode* head=CreateLink(a,3);
print(head);
AddToTail(&head,4);
print(head);
cin.get();
}
所谓链表可以这样理解:链表有多个结构体组成(当然这里说的结构体说的是看上去像结构体),每个结构体可以简化看成由两个部分组成,一个是值,另一个存放一个指针,这个指针指向下一个结构体。
这里着重讲一下void AddToTail(ListNode** pHead,int value)函数,它的第一个形参是一个指向指针的指针,mian中调用它的语句是AddToTail(&head,4)。
我们知道指针传递和引用传递可以起到修改实参的效果,那么这里的head本来就是一个指向ListNode结构体的指针,为啥还要取的指针作为实参?
原因很简答,虽然我们写程序的人知道head是一个指针,但是在编译器看来它就是一个值而已(只是这个值恰巧是指针),那么在AddToTail函数中对head进行赋值操作,肯定不会对函数外的head产生任何影响。只有把&head作为实参传递进AddToTail去,然后在函数中对*head作赋值操作,才会对函数外的head产生影响。
可以这样看,如果实参有&修饰,那就是真正意义上的指针传递,反之则不是。
所以,当对一个空链表使用AddToTail(ListNode* pHead,int value)函数时,执行下面程序段时if (pHead==NULL)
{
pHead=newNode;
return;
}此时的pHead只是一个副本,对它进行任何修改都不会改变链表,因为它只是一个局部变量,出了AddToTail就被释放掉了。
形参取**,只是为了考虑空链表的情况,如果链表不是空的,那么其实用AddToTail(ListNode* pHead,int value)函数也是完全可以的。
一个注意点:->的优先级高于*,所以*pHead->m_pNext并不能取到m_pNext的内存,只有这样写才能达到目的:(*pHead)->m_pNext。
using namespace std;
struct ListNode
{
int value;
ListNode* m_pNext;
};
void AddToTail(ListNode** pHead,int value)
{
ListNode* newNode=new ListNode();
newNode->value=value;
newNode->m_pNext=NULL;
if (pHead==NULL)
{
return;
}
if (*pHead==NULL)
{
*pHead=newNode;
return;
}
ListNode* p=*pHead;
ListNode* q=NULL;
while (p!=NULL)
{
q=p;
p=p->m_pNext;
}
q->m_pNext=newNode;
}
ListNode* CreateLink(int a[],int len)
{
ListNode* Head=NULL,*q=NULL;
for (int i = 0; i < len; i++)
{
ListNode* pNew=new ListNode();
pNew->value=a[i];
pNew->m_pNext=NULL;
if (Head==NULL)
{
Head=pNew;
q=pNew;
}
else
{
q->m_pNext=pNew;
q=pNew;
}
}
return Head;
}
void print(ListNode* head)
{
ListNode* q=head;
while (q!=NULL)
{
cout<<q->value<<endl;
q=q->m_pNext;
}
cout<<endl;
}
int main()
{
int a[]={1,2,3};
ListNode* head=CreateLink(a,3);
print(head);
AddToTail(&head,4);
print(head);
cin.get();
}
所谓链表可以这样理解:链表有多个结构体组成(当然这里说的结构体说的是看上去像结构体),每个结构体可以简化看成由两个部分组成,一个是值,另一个存放一个指针,这个指针指向下一个结构体。
这里着重讲一下void AddToTail(ListNode** pHead,int value)函数,它的第一个形参是一个指向指针的指针,mian中调用它的语句是AddToTail(&head,4)。
我们知道指针传递和引用传递可以起到修改实参的效果,那么这里的head本来就是一个指向ListNode结构体的指针,为啥还要取的指针作为实参?
原因很简答,虽然我们写程序的人知道head是一个指针,但是在编译器看来它就是一个值而已(只是这个值恰巧是指针),那么在AddToTail函数中对head进行赋值操作,肯定不会对函数外的head产生任何影响。只有把&head作为实参传递进AddToTail去,然后在函数中对*head作赋值操作,才会对函数外的head产生影响。
可以这样看,如果实参有&修饰,那就是真正意义上的指针传递,反之则不是。
所以,当对一个空链表使用AddToTail(ListNode* pHead,int value)函数时,执行下面程序段时if (pHead==NULL)
{
pHead=newNode;
return;
}此时的pHead只是一个副本,对它进行任何修改都不会改变链表,因为它只是一个局部变量,出了AddToTail就被释放掉了。
形参取**,只是为了考虑空链表的情况,如果链表不是空的,那么其实用AddToTail(ListNode* pHead,int value)函数也是完全可以的。
一个注意点:->的优先级高于*,所以*pHead->m_pNext并不能取到m_pNext的内存,只有这样写才能达到目的:(*pHead)->m_pNext。
相关文章推荐
- 给定一个单向链表,目前已经有一个指针,指向某一个节点(记作A),现在要删除这个节点A,如何操作。
- 1.01一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?
- 一个单向链表,不知道头节点,一个指针指向其中一个节点,问如何删除这个指针指向的节点?
- 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序
- 求助 向升序单向链表中插入一个节点 求教程序中哪里错了?
- 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head
- 今天开始学Java 输入一个单向链表和一个节点的值,从单向链表中删除等于该值的节点,删除后如果链表中无节点则返回空指针。
- 单向链表中,如何在给定节点前快速插入一个节点?
- 华为机试题:向升序单向链表中插入一个节点
- 【剑指offer】链表相关-链表末尾插入一个节点
- [华为机试练习题]49.向升序单向链表中插入一个节点
- 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序
- 编码实现环状单向链表(尾指针直接指向头指针,中间没有空节点),去除连续的重复元素的操作
- 华为OJ 向升序单向链表中插入一个节点
- 有一个单项的链表,在没有头结点的情况下,只知道有一个指向结点B的指针p,假设这个结点B不是尾结点,删除该节点B。
- 向升序单向链表中插入一个节点
- 21.输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判
- 面试题 单向链表(无头结点)一个指针指向其中的一个结点,如何删除这个结点?
- 单向链表中,如何在给定节点前快速插入一个节点?
- java实现输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head