现在的位置: 首页 > 综合 > 正文

PAT DS 3-05求链式线性表的倒数第K项

2016年07月05日 ⁄ 综合 ⁄ 共 1257字 ⁄ 字号 评论关闭

本想会很快写出来的程序,最后总是用了很长时间。

这题开始时用链表,大数据却是段错误和内存超限。毕竟struct貌似要额外的48字节记录信息。

#include <stdio.h>
#include <malloc.h>

typedef struct node{
	int v;
	struct node *nx;
}ND;

int main()
{
	freopen("in.txt", "r", stdin);
	int k;
	int x;
	int c=0;
	scanf("%d", &k);
	ND *p=NULL, *q=NULL, *r=NULL;
	r = (ND*)malloc(sizeof(ND));
	r->v = -1;
	r->nx = NULL;
	p = r;
	while(1){
		scanf("%d", &x);
		if(x < 0) break;
		if(c < k){
			q = (ND*)malloc(sizeof(ND));
		}
		else{
			q = p->nx;
			p->nx = q->nx;
//			free(q);
		}
		q->v = x;
		q->nx = NULL;
		r->nx = q;
		r = q;
		c++;
	}
	if(c < k)
		printf("NULL");
	else
		printf("%d", p->nx->v);
	return 0;
}

上面能保证链表长度不超过k,也不用free了。

考虑错误的原因一个是struct问题,另一个可能是OJ问题,因为自己做的10^8都没有段错误。不过之前用free不会有3号测试点的段错误。为什么呢?

补充1:

终于找到原因了,没放弃。

	while(1){
		scanf("%d", &x);
		if(x < 0) break;
		q = (ND*)malloc(sizeof(ND));
		q->v = x;
		q->nx = NULL;
		r->nx = q;
		r = q;
		c++;
		if(c > k){
			q = p->nx;
			p->nx = q->nx;
			free(q);
		}
	}

之前版本的用free,没想到这几次内存都在31300+,恰好全过了。突然发现测试点3的内存只用了256,和点1,点2一样。但3出现段错误,想到可能是k=1出错的。测试了一下,果然!

还是想了好久,最后gdb才知道是一个元素删除时引发的尾指针丢失问题

		else{
			q = p->nx;
			if(q->nx == NULL)
				r = p;
			p->nx = q->nx;
//			free(q);
		}

修改了else果然全过了!!

//

由于之前说的产生错误,不得不用简单的循环队列做。这种方法就简单明了。

#include <stdio.h>

int main()
{
	freopen("in.txt", "r", stdin);
	int k;
	int x;
	int c=0;
	int *m;
	int p=0;
	scanf("%d", &k);
	m = (int*)malloc(sizeof(int)*k);
	while(1){
		scanf("%d", &x);
		if(x < 0) break;
		m[p] = x;
		p = (p+1)%k;
		c++;
	}
	if(c < k)
		printf("NULL");
	else
		printf("%d", m[p]);
	return 0;
}

补充2:

链表算法出现的消耗超出预期的内存的原因,我的博客《malloc申请空间到底有多少 》分析了

抱歉!评论已关闭.