我是靠谱客的博主 朴素人生,最近开发中收集的这篇文章主要介绍浙大数据结构课程习题 02-线性结构1 两个有序链表序列的合并 的C语言实现代码实现思路踩坑,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

浙大数据结构课程习题 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语言实现代码实现思路踩坑所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部