数据结构-2020夏 02-线性结构3 Reversing Linked List (25分)

原题地址

https://pintia.cn/problem-sets/1268384564738605056/problems/1271415149946912770

解题思路

建议收看MOOC对应章节的小白专场~~

注意事项

写add函数的时候不认真,初始化一个指针变量p之后忘记写p->link = NULL导致测试点三一直不过...这里链表最后不是指向NULL的话,如果是零多项式就没法判断并输出0 0了,导致错误。


大家写的时候还是要细心一点~

参考代码

#include <bits/stdc++.h>
using namespace std;
#define pb push_back
typedef double db;
typedef long long LL;
typedef vector<int> VI;
typedef struct polyNode *polyNominal;

const int inf = 2e9;
const LL INF = 8e18;
const int maxn = 5e5 + 5;

struct polyNode {
	int coef;
	int expon;
	polyNominal link;
};
//在rear节点后插入新节点p
void attach(int c, int e, polyNominal *pRear) {
	polyNominal p;
	p = (polyNominal)malloc(sizeof(struct polyNode));
	p->coef = c;
	p->expon = e;
	p->link = NULL;
	(*pRear)->link = p;
	*pRear = p;
}
//读入多项式,返回链表头节点指针 
polyNominal read() {
	polyNominal p, rear, t;
	int c, e, N;
	
	scanf("%d", &N);
	p = (polyNominal)malloc(sizeof(struct polyNode));
	p->link = NULL;
	rear = p;
	while (N--) {
		scanf("%d%d", &c, &e);
		attach(c, e, &rear);  //引用的是变量的地址,即这里是指针变量的指针,所以等下要用* 
	}
	t = p; p = p->link; free(t);  //删除空的头结点 
	return p;
}
//将两个多项式相加的函数,返回得到头结点指针 
polyNominal add(polyNominal p1, polyNominal p2) {
	polyNominal t1, t2, p, rear, t;
	t1 = p1; t2 = p2;
	p = (polyNominal)malloc(sizeof(struct polyNode));
	p->link = NULL;  //找这个错找了好久,忘记写这个导致测试点3一直过不了 
	rear = p;
	//将t1和t2进行相加,若有一个链表处理完即退出循环 
	while (t1 && t2) {
		if (t1->expon == t2->expon) {
			if (t1->coef + t2->coef) {  //同类项相加之后不为0,再进行插入 
				attach(t1->coef + t2->coef, t1->expon, &rear);
			}
			t1 = t1->link;
			t2 = t2->link;
		} else if (t1->expon > t2->expon) {
			attach(t1->coef, t1->expon, &rear);
			t1 = t1->link;
		} else {
			attach(t2->coef, t2->expon, &rear);
			t2 = t2->link;
		}
	}
	//处理可能非空的链表,接到p后面 
	while (t1) {
		attach(t1->coef, t1->expon, &rear);
		t1 = t1->link;
	}
	while (t2) {
		attach(t2->coef, t2->expon, &rear);
		t2 = t2->link;
	}
	
/*
	while (t2) {
		attach(t2->coef, t2->expon, &rear);
	}*/
	//释放空的头结点
	t = p; p = p->link; free(t);
	return p;
}
//将多项式输出
void printPoly(polyNominal p) {
	int flag = 0;  //辅助调整输出格式
	
	if (!p) {
		printf("0 0\n");
		return;
	}
	
	while (p) {	
		if (!flag) flag = 1;
		else printf(" ");
		printf("%d %d", p->coef, p->expon);
		p = p->link;
	}
	printf("\n");
}
//将两个多项式相乘的函数
polyNominal mult(polyNominal p1, polyNominal p2) {
	polyNominal p, rear, t1, t2, t;
	int c, e;
	
	/*判断:如果p1或p2是零项则返回NULL*/
	if (!p1 || !p2) return NULL; 
	
	p = (polyNominal)malloc(sizeof(struct polyNode));
	p->link = NULL;
	rear = p;
	t1 = p1; t2 = p2;
	//先让p1的第一项和p2所有相乘,得到p 
	while (t2) {
		attach(t1->coef * t2->coef, t1->expon + t2->expon, &rear);
		t2 = t2->link;
	}
/*	printf("p1相乘结果为:");
	printPoly(p);
	printf("\n");*/
	t1 = t1->link;
	while (t1) {
		t2 = p2;
		rear = p;  /*容易忘记初始化rear!!!*/
		while (t2) {
			e = t1->expon + t2->expon;
			c = (t1->coef) * (t2->coef);
			/*难点:判断在哪里进行插入/进行系数相加*/
			while (rear->link && rear->link->expon > e) {
				rear = rear->link;
			}
			if (rear->link && rear->link->expon == e) {
				if (rear->link->coef + c)
					rear->link->coef += c;
				else {
					t = rear->link;
					rear->link = t->link;
					free(t);
				}
			}
			else {
				t = (polyNominal)malloc(sizeof(struct polyNode));
				t->coef = c;
				t->expon = e;
				t->link = rear->link;
				rear->link = t;
				rear = rear->link;
			}
			t2 = t2->link;			
		}
		t1 = t1->link;
/*		printf("此时为:");
		printPoly(p);
		printf("\n");*/
	}
	t = p; p = p->link; free(t);
	return p;
}

int main() {
	polyNominal p1, p2, pp, ps;
	
	p1 = read(); p2 = read();
	//cout << "p1:" << p1 << endl;
	
	pp = add(p1, p2);
	//cout << "add:" << pp;
	ps = mult(p1, p2);
	printPoly(ps);
	printPoly(pp);
	
	return 0;
}

 

题目描述 给定一个常数 $K$ 以及一个单链表 $L$,请编写程序将 $L$ 中每 $K$ 个结点反转。例如:给定 $L$ 为 1→2→3→4→5→6,$K$ 为 3,则输出应该为 3→2→1→6→5→4;如果 $K$ 为 4,则输出应该为 4→3→2→1→5→6,即最后不到 $K$ 个元素不反转。 输入格式 每个输入包含一个测试用例。每个测试用例第 1 行给出第 1 个结点的地址、结点总个数正整数 $N (\le 10^5)$、以及正整数 $K (\le N)$,即要求反转的子链结点的个数。结点的地址是 5 位非负整数,NULL 地址用 −1 表示。 接下来有 $N$ 行,每行格式为: Address Data Next 其中 Address 是结点地址;Data 是该结点保存的整数数据;Next 是下一结点的地址。题目保证给出的链表不为空。 输出格式 对每个测试用例,顺序输出反转后的链表,其上每个结点占一行,格式与输入相同。 输入样例 00100 6 4 00000 4 99999 00100 1 12309 68237 6 -1 33218 3 00000 99999 5 68237 23333 2 33218 输出样例 00000 4 33218 33218 3 12309 12309 1 99999 99999 5 68237 68237 6 23333 23333 2 -1 题目析 本题需要将链表中每 $K$ 个结点反转,可以采用迭代的方法,每次找到 $K$ 个结点,将这 $K$ 个结点反转,然后将这 $K$ 个结点的前驱结点指向反转后的第一个结点,将反转后的 $K$ 个结点的最后一个结点指向下一个要反转的结点,然后继续进行下一轮反转。 需要注意的是,如果链表长度不足 $K$,则不进行反转。 代码实现
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值