PAT乙级1025反转链表 25(分)

1025 反转链表 (25 分)

给定一个常数 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 个元素不反转。
原题链接

代码

#include <iostream>
#include <algorithm>
using namespace std;
int main() {
	int firstadd, n, k;
	cin >> firstadd >> n >> k;
	int nextaddr[100010], data[100010], addrlist[100010];
	for (int i = 0; i < n; i++) {
		int addrtemp;
		cin >> addrtemp;
		cin >> data[addrtemp] >> nextaddr[addrtemp];
	}
	int sum = 0;//在链表中的节点总数
	int next = firstadd;
	while (next != -1) {
		addrlist[sum++] = next;
		next = nextaddr[next];
	}//循环完成之后,sum就是总的有效节点数
	//下面进项列表反转
	for (int i = 0; i < (sum - sum%k); i += k) {
		// reverse(begin(addrlist)+i, begin(addrlist)+i+k);
		reverse(addrlist+i, addrlist+i+k);
	}
	// 下面进行输出
	for (int i = 0; i < sum - 1; i++) {//先输出前sum-1项
		printf("%05d %d %05d\n", addrlist[i], data[addrlist[i]], addrlist[i+1]);
	}
	//再输出最后一项
	printf("%05d %d -1", addrlist[sum-1], data[addrlist[sum-1]]);
	return 0;
}

题解

  • 对于这种线性表,可以优先考虑设置一个较大的数组以下标作为本节点地址,以数组内的数据作为下个节点的地址,即数组nextaddr[presentaddr],空间换时间,不用遍历所有节点就能串起来所有节点。

  • 对于反转操作,可以专门用一个数组来存储正常的顺序,即addrlist[100010],这样,data只跟地址有关,与前后地址都没关系,就方便输出了~

  • 注意,下面的写法是错误的:

    int temp;
    cin >> temp >> a[temp];
    

    应该拆开来写:

    int temp;
    cin >> temp;
    cin >> a[temp];
    
  • 刷算法题,能用cin,cout 就用之,代码简洁好看!如果超时了或者输出格式需要控制再用printf。

c++中的reverse()函数

reverse函数多用于字符串、数组、容器。头文件是#include <algorithm>
reverse函数的功能是Reverses the order of the elements in the range [first,last)
参考:reverse的官方说明

  • 对数组反转可以使用algorithm下的reverse(begin(), end()),参数是指针(简单理解为地址)一类的。

  • 需要注意的是,reverse中的参数如果是容器,可以写成reverse(cont.begin(), cont.end()) 或者reverse(begin(cont), end(cont))。但是reverse中的参数如果是数组,则只能写成reverse(begin(arr), end(arr))begin()用于数组时返回数组指针,用于容器时返回cont.begin()。本题代码中,这两句话是一样的:

    	reverse(begin(addrlist)+i, begin(addrlist)+i+k);
    	reverse(addrlist+i, addrlist+i+k);
    
  • 参考:C++ STL begin()和end()函数用法(推荐)、https://www.cplusplus.com/reference/iterator/begin/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值