更新:优化文章结构,增加了部分内容如(1110区块反转)和自己代码和他人代码分析。看完你就懂了

转载请注明出处和链接地址:(https://www.cnblogs.com/ahappyfool/p/17156470.html)

我优化并且总结分解为以下四个步骤:

  1. 第一先建立结构体,并且将这些输入数据储存起来,怎么储存呢?用结构体数组存,注意:想要存下这些数据,他们的下标都非常大,也就是要大数组。这个大数组得在main函数外定义。
  2. 在输入完链表之后,遍历链表使用另一个数组(可以是指针数组也可以是节点数组)记录下该节点的地址或者将节点的顺序调对,并且记录有多少个节点(加个变量记录就行,还可以用来作为变化的数组下标),读到-1停止。注意不能使用小于n作为终止条件,会有像-1 0 -1这样的无效节点被读入。
  3. 对该指针数组进行操作:反转还是什么,按题目要求。
  4. 然后就进行对应的操作输出就行了

下面是我做的一题:pat乙级1110区块反转。给你们演示一下步骤分析和一些应该注意的点

#include<bits/stdc++.h>
using namespace std;
//第一步
struct node {
int addr,data, next;
}list1[100000];
node*b[100000][500]; //使用二维数组将已经储存了每个节点地址的变量分块
int main(){
node* a[100005];
int first,n,k;cin>>first>>n>>k;
for (int i = 0; i < n; i++) {
int a1;
scanf("%d", &a1);
list1[a1].addr=a1;
scanf("%d%d", &list1[a1].data, &list1[a1].next);
}
//第二步
int tmp = first,ihh=0; //不要忘记ihh作为变量记录有效节点个数
while(tmp!=-1){
a[ihh++]=&list1[tmp];
tmp=list1[tmp].next;//遍历
}
//第三步:
int num=ihh/k,cnt=0;
if(num*k<ihh)num++;
for(int i=0;i<num;i++){
for(int j=0;j<k&&cnt<ihh;j++){
b[i][j]=a[cnt++];//分块
}
}
//第四步
cnt=0;int kkk=ihh-num*k+k;
for(int i=num-1;i>=0;i--){
for(int j=0;j<kkk;j++){
if(i==num-1&&j==0)printf("%05d %d ",b[i][j]->addr
,b[i][j]->data);//第一个数据都是这样输入的
else printf("%05d\n%05d %d ",b[i][j]->addr,
b[i][j]->addr,b[i][j]->data);//后面这样
}
kkk=k;
}
printf("-1");//补个-1
return 0;
}

pat中还有关于链表的三个题目1025:反转链表,1075,链表元素分类,1100,链表合并。你们可以分析以下代码和我的代码有什么不同之处。相信你会有所收获

以下代码来自柳婼的博客

1025:反转链表

	#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int first, k, n, temp;
cin >> first >> n >> k;
int data[100005], next[100005], list[100005];
for (int i = 0; i < n; i++) {
cin >> temp;
cin >> data[temp] >> next[temp];
}
int sum = 0;//不⼀定所有的输⼊的结点都是有⽤的,加个计数器
while (first != -1) {
list[sum++] = first;
first = next[first];
}
for (int i = 0; i < (sum - sum % k); i += k)
reverse(begin(list) + i, begin(list) + i + k);
for (int i = 0; i < sum - 1; i++)
printf("%05d %d %05d\n", list[i], data[list[i]], list[i + 1]);
printf("%05d %d -1", list[sum - 1], data[list[sum - 1]]);
return 0;
}

1075:链表元素分类

		将结点⽤list[10000]保存, list为node类型, node中保存结点的值value和它的next地址。 list的下标就是结点的地址。将<0、 0~k、 >k三部分的结点地址分别保存在v[0]、 v[1]、 v[2]中,最后将vector中的值依次输出即可  .即只遍历一次,减少遍历次数
#include <iostream>
#include <vector>
using namespace std;
struct node {
int data, next;
}list[100000];
vector<int> v[3];
int main() {
int start, n, k, a;
scanf("%d%d%d", &start, &n, &k);
for (int i = 0; i < n; i++) {
scanf("%d", &a);
scanf("%d%d", &list[a].data, &list[a].next);
}
int p = start;
while(p != -1) {
int data = list[p].data;
if (data < 0)
v[0].push_back(p);
else if (data >= 0 && data <= k)
v[1].push_back(p);
else
v[2].push_back(p);
p = list[p].next;
}
int flag = 0;
for (int i = 0; i < 3; i++) {
for (int j = 0; j < v[i].size(); j++) {
if (flag == 0) {
printf("%05d %d ", v[i][j], list[v[i][j]].data);
flag = 1;
}
else {
printf("%05d\n%05d %d ", v[i][j], v[i][j], list[v[i][j]].data);
}
}
}
printf("-1");
return 0;
}

1105:链表合并:⽤vector L1、 L2存储题⽬中给定的两个链表, vector ans保存合并后的链表。将较⻓的⼀个链表存储在L1中,如果原本L1较短,则将L1与L2⽤swap函数互相置换~在链表合并的过程中, i从0开始,将L1中每个结点添加到ans中,如果当前i是奇数(i & 1不等于0)就把L2的⼀个结点添加到ans中,直到L2中没有剩余元素,反复,我是遍历了两遍,然后如果大小区分就swap首地址。

#include <iostream>
#include <vector>
using namespace std;
struct node {
int data, next;
}A[100000];
vector<int> L1, L2, ans;
int sa, sb, n, a, ta, tb, c;
int main() {
cin >> sa >> sb >> n;
for (int i = 0; i < n; i++) {
cin >> a >> A[a].data >> A[a].next;
}
ta = sa;
while (ta != -1) {
L1.push_back(ta);
ta = A[ta].next;
}
tb = sb;
while (tb != -1) {
L2.push_back(tb);
tb = A[tb].next;
}
if (L1.size() < L2.size()) swap(L1, L2);
for (int i = 0, c = L2.size() - 1; i < L1.size(); i++) {
ans.push_back(L1[i]);
if (i & 1 && c >= 0) ans.push_back(L2[c--]);
}
for (int i = 1; i < ans.size(); i++) {
printf("%05d %d %05d\n", ans[i-1], A[ans[i-1]].data, ans[i]);
}
printf("%05d %d -1", ans.back(), A[ans.back()].data);
return 0;
}

总结:

  1. 你会发现可以不用指针数组,而采用结构体数组存储,
  2. 地址其实就等于结构体数组的下标,完全可以不用addr这个变量来记录地址,因为它是可以通过其他方式来表示出来的。但是我为什么还要采用有addr的结构体呢?这种方式,更容易理解,更加利于输出和思考,地址和data有相同的输出方式。

    3.方法要适合自己的方法才是好方法

    部分思路来自:

    看完后思路清晰:1025链表一连a三题链表题。

pat乙级:模拟链表问题(汇总,包含所有pat中链表题目分析)的更多相关文章

  1. PAT乙级真题及训练题 1025. 反转链表 (25)

    PAT乙级真题及训练题 1025. 反转链表 (25) 感觉几个世纪没打代码了,真是坏习惯,调了两小时把反转链表调出来了,心情舒畅. 这道题的步骤 数据输入,数组纪录下一结点及储存值 创建链表并储存上 ...

  2. PAT乙级考前总结(三)

    特殊题型 1027 打印沙漏 (20 分) 题略,感觉有点像大学里考试的题.找规律即可. #include <stdio.h>#include <iostream>using ...

  3. PAT乙级:1069 微博转发抽奖 (20分)

    PAT乙级:1069 微博转发抽奖 (20分) 题干 小明 PAT 考了满分,高兴之余决定发起微博转发抽奖活动,从转发的网友中按顺序每隔 N 个人就发出一个红包.请你编写程序帮助他确定中奖名单. 输入 ...

  4. C#版 - PAT乙级(Basic Level)真题 之 1021.个位数统计 - 题解

    版权声明: 本文为博主Bravo Yeung(知乎UserName同名)的原创文章,欲转载请先私信获博主允许,转载时请附上网址 http://blog.csdn.net/lzuacm. C#版 - P ...

  5. PAT 乙级 1024

    题目 题目地址:PAT 乙级 1024 题解 模拟题,重点需要考虑到各种不同情况:简单来说一下: 因为输入格式固定,所以把不同的部分分别存储和处理可以在很大程度上简化运算:其中需要考虑最多的就是小数部 ...

  6. PAT 乙级 1017

    题目 题目地址:PAT 乙级 1017 题解 粗看是一道大数除法题,实际上只不过是通过字符数组模拟除法过程,理解之后还是比较简单的: 具体分析一下本题: 因为题设中的除数(n)是一位整数,因此大幅简化 ...

  7. 1054. 求平均值 (20)-PAT乙级真题

    今天刚刚到学校,2017年学习正式开始了,今天看到了浙大的<数据结构>这学期又要开课了,决定一定要跟着学习一遍:在大学生mooc网上学习:http://www.icourse163.org ...

  8. PAT 乙级 1007. 素数对猜想 (20) c++ 筛选法求素数

    PAT 乙级 1007. 素数对猜想 (20) c++ 筛选法求素数 让我们定义 dn 为:dn = pn+1 - pn,其中 pi 是第i个素数.显然有 d1=1 且对于n>1有 dn 是偶数 ...

  9. PAT乙级:1014 福尔摩斯的约会 (20分)

    PAT乙级:1014 福尔摩斯的约会 (20分) 题干 大侦探福尔摩斯接到一张奇怪的字条:我们约会吧! 3485djDkxh4hhGE 2984akDfkkkkggEdsb s&hgsfdk ...

  10. PAT乙级:1070 结绳 (25分)

    PAT乙级:1070 结绳 (25分) 题干 给定一段一段的绳子,你需要把它们串成一条绳.每次串连的时候,是把两段绳子对折,再如下图所示套接在一起.这样得到的绳子又被当成是另一段绳子,可以再次对折去跟 ...

随机推荐

  1. vue设计与实现 第6章 ref 响应原理 笔记

    ref 函数实现代码 const a = ref(1); function ref(value){ const wrapper = {value} Object.defineProperty(wrap ...

  2. week_10

    Andrew Ng 机器学习笔记 ---By Orangestar Week_10 (大数据处理) 1. Learning With Large Datasets 机器学习很多时候都要处理非常多的数据 ...

  3. python从公众号文章中获取二维码

    在做一个公众号采集的项目中,客户有个要求,想把二维码的url保存到数据库中,如图. 原本以为要各种骚操作各种逆向才能获取得到,没想到竟然很简单. 第一步 观察二维码url的规范 https://mp. ...

  4. Django简介以及基本使用

    目录 Django简介以及基本使用 一.django简介 1.web框架的本质是什么 ? 2.python主流web框架有那些 ? 3.web框架的推导过程 二.基本使用 1.运行django注意事项 ...

  5. [编程基础] C++多线程入门5-使用互斥锁解决资源竞争

    原始C++标准仅支持单线程编程.新的C++标准(称为C++11或C++0x)于2011年发布.在C++11中,引入了新的线程库.因此运行本文程序需要C++至少符合C++11标准. 文章目录 5 使用互 ...

  6. Spark详解(09) - Spark调优

    Spark详解(09) - Spark调优 Spark 性能调优 常规性能调优 常规性能调优一:最优资源配置 Spark性能调优的第一步,就是为任务分配更多的资源,在一定范围内,增加资源的分配与性能的 ...

  7. .Net 7 内存模型函数描述结构MethoDesc

    楔子 讲一些CLR里面的内存模型.本篇MethodDesc,意为函数的描述之意,看下一个函数在CLR里面是如何被描述的. MethodDesc结构 这个结构体在CLR里面高达1600多行,这里仅截取一 ...

  8. cookie设置失败

    有个小项目,本地测试一帆风顺,昨天发布到云服务器后就出问题了 Java端设置的Cookie,浏览器访问不到 1-2022-2-11 设置cookie代码如下 /** * 添加Cookie * @par ...

  9. Miller-Rabin 与 Pollard-Rho 算法学习笔记

    前言 Miller-Rabin 算法用于判断一个数 \(p\) 是否是质数,若选定 \(w\) 个数进行判断,那么正确率约是 \(1-\frac{1}{4^w}\) ,时间复杂度为 \(O(\log ...

  10. P5683 [CSP-J2019 江西] 道路拆除

    简要题意 给你一个 \(m\) 条边 \(n\) 个点的无向图.你需要去掉一些边,使得 \(1 \to s_1,1 \to s_2\) 连通,且 \(1 \to s_1\) 的最短路径长度小于 \(t ...