概述
浙大数据结构课程习题 02-线性结构1 两个有序链表序列的合并 的C语言实现
- 代码实现
- 思路
- 踩坑
- 1. 思路没有先确定
- 2. 忘记头结点(审题)
- 3.关于指针的本质
- 4.关于free与赋NULL值的问题
这道题的解法已经有很多版本了,博主在这里主要是分享一下自己踩的坑以及可行的解决办法。
代码实现
List Merge( List L1, List L2 )
{
List tempL1 = L1;
List tempL2 = L2;
tempL1 = L1->Next;
tempL2 = L2->Next;
List L3 = (PtrToNode)malloc(sizeof(struct Node));
List tail = L3;
while ( tempL1 && tempL2 ) {
if ( tempL1->Data <= tempL2->Data ) {
tail->Next = tempL1;
tail = tail->Next;
tempL1 = tempL1->Next;
} else {
tail->Next = tempL2;
tail = tail->Next;
tempL2 = tempL2->Next;
}
}
if ( tempL1 ) {
tail->Next = tempL1;
} else if ( tempL2 ){
tail->Next = tempL2;
}
L1->Next = NULL;
L2->Next = NULL;
//free(L1->Next);
//free(L2->Next);
return L3;
}
思路
这道题就是用一个目标链表,不断放入待处理两个链表中的较小元素,最后当一个链表为空时跳出循环,直接将非空链表所有元素连到目标链表上,时间复杂度为 O ( n ) O(n) O(n)。
踩坑
这道题初看以为10min以内能搞定没想到又断断续续搞了一个小时…说到底还是基础知识不过关。
1. 思路没有先确定
最开始直接上手做,就想当然地以为要为目标链表不断新建内存,然后将两个待处理链表中的值一个一个保存进去,后来试了一下是可以的,代码如下:
List Merge( List L1, List L2 )
{
List tempL1 = L1;
List tempL2 = L2;
tempL1 = L1->Next;
tempL2 = L2->Next;
List L3 = (PtrToNode)malloc(sizeof(struct Node));
List tail = L3;
while ( tempL1 && tempL2 ) {
if ( tempL1->Data <= tempL2->Data ) {
tail->Next = (PtrToNode)malloc(sizeof(struct Node));
tail->Next->Data = tempL1->Data;
tail->Next->Next = NULL;
tail = tail->Next;
tempL1 = tempL1->Next;
} else {
tail->Next = (PtrToNode)malloc(sizeof(struct Node));
tail->Next->Data = tempL2->Data;
tail->Next->Next = NULL;
tail = tail->Next;
tempL2 = tempL2->Next;
}
}
if ( tempL1 ) {
tail->Next = tempL1;
} else if ( tempL2 ){
tail->Next = tempL2;
}
L1->Next = NULL;
L2->Next = NULL;
//free(L1->Next);
//free(L2->Next);
return L3;
}
不过显然,代码量增加了许多,这还是if和if-else没有改成上面的模式的前提下,这里只是说明如果思路不提前想好,工作量会增加许多的问题。
2. 忘记头结点(审题)
本题题目明确说明要考虑头结点,但是因为对链表操作还不是很熟悉就没在意,但是在系统测试的时候频繁出现段错误,因此就将头结点思考了一下,结果发现应该在函数头就把指针后移一位就ok了。
3.关于指针的本质
代码中有一行是
List tail = L3;
后来操作的都是tail但是返回的是L3,这样L3的值会改变吗?但是其实在操作tail的时候,因为tail和L3都指向同一块内存,因此返回tail和L3本质上是一样的,而tail上做的改变同样也能够被带出函数,因为传入的是Node*,因此对Node的值改变是被允许的。
4.关于free与赋NULL值的问题
最在如下代码中
L1->Next = NULL;
L2->Next = NULL;
//free(L1->Next);
//free(L2->Next);
当时我以为直接free掉头结点以后的内存只留头结点不就可以了吗,但是其实只free是把指针指向的内存空间释放了,并没有将指针的值赋为NULL,指针仍然指向这块内存。而一般都用if语句来测试指针是否为NULL判断,因此,如果不赋值为NULL,则会导致指针成为“野指针”。
因此,我们要么直接将next赋为NULL,要么free后再置NULL,当然要避免内存泄漏还是后者保险一些。
这些都是目前经过上网查找的知识尚未经检验,如有疏漏,还望指正~
最后
以上就是朴素人生为你收集整理的浙大数据结构课程习题 02-线性结构1 两个有序链表序列的合并 的C语言实现代码实现思路踩坑的全部内容,希望文章能够帮你解决浙大数据结构课程习题 02-线性结构1 两个有序链表序列的合并 的C语言实现代码实现思路踩坑所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复