[C++学习]剑指offer13题的学习笔记

问题描述:用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
int* ip=&i;将ip指向i 
void reset(int &ip)
{
	ip = 0; 
}
int i = 42;
reset(i);//改变的是i的值,而非i的地址
cout << i << endl; //输出为0
int& ip=i;其实ip是i的别名,可以通过改变ip来改变i。
返回问题中来pToBeDeleted = pToBeDeleted->m_pNext;改变了形参所指的对象,未能对实参产生影响。pToBeDeleted->m_nValue =pToBeDeleted->m_pNext->m_nValue;改变了形参所指对象的值。

4.书上的参考答案为什么必须删除下个结点?

我试了一下不删除结点也对,没有报错。可能涉及到了空间释放、安全等问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值