编程珠玑 第十三章 习题4 思考

本文深入解析《编程珠玑》第十三章课后习题中关于链表迭代插入的实现方式,通过具体代码示例解释指针的巧妙运用,帮助读者理解如何避免处理特殊情形。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编程珠玑第十三章 课后习题第4题:为链表重写相应的迭代版本

课后习题给出了如下版本:可以避免对特殊情况的处理

	void insert2(int x)
	{
		node **p;  
		for (p = &head; (*p)->val < x; p = &((*p)->next))
		//找到第一个大于等于(*p)->val的节点  
			;  
		if ((*p)->val == x)  //当已在表中,则直接返回
			return;  
		*p = new node(x, *p);//当不在表中,则新建节点
		n++;  

	}
刚开始我以为这段程序错了,因为感觉它跟一般的遍历插入并无差别,后来经过VS调试程序后,发现原来是我错了。错误的原因应该是对指针的指针理解不够深,因此标记一下,为后来有同样有疑惑的人解惑。

这段程序的关键点在于:

1、当插入节点在首节点,由于p的初始值是&head,因此直接执行

*p = new node(x, *p);

利用node的构造函数,新插入节点的next指针正确了,然后改变*p的值也即改变了head的值,因此head指针也改变了,因此对于这种情况是可以正常处理的。

2、当插入位置不在首节点,在中间某一位置(哨兵是最大值,所有插入节点的值都小于它),因此执行for循环找到第一个大于等于x的节点,若x已在表中,则直接返回。当x不在表中,则执行

*p = new node(x, *p);//当不在表中,则新建节点
n++;  
这里才是关键点,乍一看觉得这里只改变了新建节点的next域,而前面那个节点并没有把指针指向这个新节点,事实上,错误在于对*p的理解。*p其实是前面那个节点的next域的值,因此这条语句先改变了自己的next指针,然后改变了前驱节点的next指针,因此正确!

是不是感觉很棒!当我理解了这段程序时,真的是有“顿悟”的感觉,大牛给出的代码,要看懂都不容易啊,十分精妙的代码!这也告诉了我,当对代码不理解时,调试一遍说不定能给你启发。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值