问题描述:用O(1)时间删除链表中的指定结点。
下面是学习遇到的困惑和解决方法:
1. 如何去引用结构体中的成员。
首先定义了一个结构体:
struct ListNode
{
int m_nValue;
ListNode* m_pNext;
};
利用->和.去引用结构体中的成员:
ListNode* p=new ListNode;
p->m_nValue = i;
p->m_pNext = NULL;
ListNode p;
p.m_nValue = i;
p.m_pNext = NULL;
其中“->“用于指针类型的类的实例,而“.“用于普通对象(非指针类型)的引用。
两者最大的区别是->前面放的是指针,而.前面跟的是结构体变量
例如:
struct A
{
int a;
int b;
};
A *point =malloc(sizeof(struct A));
cout<<point->a<<endl;//输出1
A object;
cout<<object.a <<endl;//输出1
2. 题目给出的函数是 voidDeleteNode(ListNode** pListHead,ListNode* pToBeDeleted);**代表指向指针的指针,该如何认识它?
参考文章(让你不再害怕指针——C指针详解(经典,非常详细))
将函数的传参写出:
ListNode** pListHead=& pNode1;
&: &a的运算结果是一个指针,指针的类型是a的类型加个*
*:*p简而言之是p所指向的东西。
了解指针需要了解指针的四个内容:
a.指针的类型:把指针的名字去掉
b.指针所指向的类型:去掉指针的名字+名字左边的*
c.指针本身所占的内存区
d.指针所指的内存区:
因此,可以看出ListNode是指向pNode1的指针的指针,也相当于:
ListNode* pListHead =pNode1;但前者在引用值:
(*pListHead)->m_nValue。后者在引用值:pListHead->m_nValue。
3. 为什么要指针和值分别赋值?不用直接将结点赋值?也就是说
pToBeDeleted->m_nValue =pToBeDeleted->m_pNext->m_nValue;
pToBeDeleted->m_pNext =pToBeDeleted->m_pNext->m_pNext;
//pToBeDeleted = pToBeDeleted->m_pNext;//为什么分开赋值可以成功,但是直接赋值就不可以?
我想应该函数值传参的原因,直接赋值,其实是把pToBeDelete转换到了next上,对实际的list未能产生影响。而逐个赋值涉及到了指针,由此改变了list
学习C++primer函数传参那节可以解决这个困惑。函数的参数传递分为两类,一是值传递,二是引用传递。值传递是对变量的改动,并不会改变实参值;而引用传递与变量初始化的机理一致,其实是一个对象的别名,可以通过改变其引用来改变实参值。通过下面的例子去理解它:
void reset(int *ip)
{
*ip = 0; //改变了指针ip所指对象的值
ip = 0;//ip的指向改变
}
reset(&i);//改变的是i的值,而非i的地址
int i = 42;
cout << i << endl; //输出为0
void reset(int &ip)
{
ip = 0;
}
int i = 42;
reset(i);//改变的是i的值,而非i的地址
cout << i << endl; //输出为0
int& ip=i;其实ip是i的别名,可以通过改变ip来改变i。