Reversing Linded list【数据结构测试2.1】

2024-01-22 10:08

本文主要是介绍Reversing Linded list【数据结构测试2.1】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

PAT 1074. Reversing Linked List,作为课后题出现在数据结构MOOC上。
刚开始学数据结构,水平还差的远尴尬 ,参考网上code,参考:http://tech-wonderland.net/blog/pat-1074-reversing-linked-list.html
路漫漫其修远兮奋斗

也是刚开始没有理解好题目意思,导致有几处感觉有难度,后来才发现是想多了。
几个需要注意的地方:
1、链表反转长度K要注意分情况讨论:<1的时候,>链表长度N的时候, =2的时候(此处要注意输入数据是多链表的时候,要修正有效链长)
2、只有1个节点的时候,输出问题
3、输入数据的K>N的时候,还是要注意重新修正有效链长,与1中提到的情况关联,否则可能会出现死循环的情况

详细讨论在代码后面:(代码为了方便自己以后看,注释较多= =)
#include "stdafx.h"
#include <fstream>
#include<vector>  
#include <iostream>
#include <iomanip>
using namespace std;  const int MaxSize = 100004;
int ihead;//头结点
int N,K;//node个数N,需要反转的node个数K
struct Node{int iData;int iNext;
};Node NodeList[MaxSize];//链表void doPrint(int ilisthead)//输入表头,输出整表
{while(-1 != ilisthead){if(NodeList[ilisthead].iNext == -1)//只有一个节点或者多个链表的时候只打印第一个{cout<<setw(5)<<setfill('0')<<ilisthead<<" "<<NodeList[ilisthead].iData<<" "<<"-1"<<endl;break;}cout<<setw(5)<<setfill('0')<<ilisthead<<" "<<NodeList[ilisthead].iData<<" "<<setw(5)<<setfill('0')<<NodeList[ilisthead].iNext<<endl;ilisthead = NodeList[ilisthead].iNext;//指向下个节点}
}//反转指定长度的节点(一次)
int reversK(int istart,int ik,int *phead,int *ptail)
{if(-1 == istart || ik <= 1)return -1;if(2 == ik){int node1 = istart;int node2 = NodeList[istart].iNext;NodeList[node1].iNext = NodeList[node2].iNext;//交换头尾NodeList[node2].iNext = node1;*phead = node2;//向后移动*ptail = node1;return 0;}// >=3的情况*ptail = istart;//保存表头,作为最后的表尾int node1 = istart;int node2 = NodeList[istart].iNext;int nodeTmp = -1;for(int i = 0; i < ik - 1; ++i)//反转ik个节点需要改变ik-1个连接关系{//暂存node2下个元素地址后改为指向node1nodeTmp = NodeList[node2].iNext;NodeList[node2].iNext = node1;//node1,node2同时向后移动node1 = node2;node2 = nodeTmp;}*phead = node1;//原来最后一个元素作新的表头NodeList[*ptail].iNext = node2;//新表尾指向node2,下一个元素或者NULL(所有元素处理完)//cout<<node2<<endl;return 0;
}void process(){//将整个链表反转//get the Effective Lenthgthint itemp = ihead;int iEffectiveLenth = 1;//链表有效长度while(-1 != NodeList[itemp].iNext) {			++iEffectiveLenth;			itemp = NodeList[itemp].iNext;			}				if(K > iEffectiveLenth) {					doPrint(ihead);	return;}	N = iEffectiveLenth;//注意!!此处细节也不可忽略,处理链表的时候需要重新设定链表的有效长度,因为在输入是多个链表的情况下有可能会出错//cout<<N<<endl;int inewhead;if(K > 1){int iheadtmp,itailtmp;int ilasttail;//记录上次反转的尾部//先反转一次,并记录翻转后的头尾reversK(ihead,K,&iheadtmp,&itailtmp);inewhead = iheadtmp;//注意!!此处inewhead是有用的,第一次反转以后,新的链表头已经产生了,即原来的链表的第K个节点!因此下面输出链表的时候要从这个新的节点开始输出!ilasttail = itailtmp;int revcount = N / K -1;//剩余反转次数for(int i = 0; i < revcount; ++i){reversK(NodeList[itailtmp].iNext,K,&iheadtmp,&itailtmp);NodeList[ilasttail].iNext = iheadtmp;//上一次反转后尾部指向此次反转完成的头(本来指向此次反转前的尾部)(不好理解的话见下面!示意图!)ilasttail = itailtmp;			}}else//K<=1的时候新的表头还是原来的表头inewhead = ihead;doPrint(inewhead);//从新的表头开始输出}
int main()  
{ fstream cin("a.txt");for(int i  = 0; i < MaxSize; ++i)//initial the whole list{NodeList[i].iData = 0;NodeList[i].iNext = -1;}cin>>ihead>>N>>K;int iadd,idata,inext;for(int i = 0; i < N; ++i)//读入链表{cin>>iadd>>idata>>inext;NodeList[iadd].iData = idata;NodeList[iadd].iNext = inext;}process();return 0;
}

关于几点注意的讨论:
1、process()函数最后那个循环里注释部分的示意图:

2、容易忽略的一个小细节,即当输入数据不止一个串的时候要及时更新有效长度,即只处理第一个串。

N = iEffectiveLenth;//此句注意,不可忽略,处理链表的时候需要重新设定链表的有效长度,因为在输入是多个链表的情况下有可能会出错(陷入死循环,配合上图和下面的讨论不难理解)
测试数据:(多串情况)
00100 6 3
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 -1


<pre name="code" class="cpp">for(int i = 0; i < ik - 1; ++i)//反转ik个节点需要改变ik-1个连接关系{//暂存node2下个元素地址后改为指向node1nodeTmp = NodeList[node2].iNext;NodeList[node2].iNext = node1;//node1,node2同时向后移动node1 = node2;node2 = nodeTmp;}

 

N影响的是下面的循环次数,而下面的又调用了上面的这段函数,因此当使用最上面的数据的时候,当k=2的时候,正确的情况应该是,由于有多个链表,N需要重新设定有效长度,重新设定以后应该为2,因此,下面的程序只循环一次;
但当N不重新设定有效长度的时候,循环次数为两次,循环过两次之后的情况就是,节点1指向节点2,节点2指向-1,(由于-1的下个节点还是-1,)因此再一次循环的时候,再执行下面的语句:
nodeTmp = NodeList[node2].iNext;NodeList[node2].iNext = node1;//node1,node2同时向后移动node1 = node2;node2 = nodeTmp;

然后,节点2就指向了节点2本身了。
且节点2作为头结点,因此输出的时候形成死循环。


这篇关于Reversing Linded list【数据结构测试2.1】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/632652

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

【数据结构】——原来排序算法搞懂这些就行,轻松拿捏

前言:快速排序的实现最重要的是找基准值,下面让我们来了解如何实现找基准值 基准值的注释:在快排的过程中,每一次我们要取一个元素作为枢纽值,以这个数字来将序列划分为两部分。 在此我们采用三数取中法,也就是取左端、中间、右端三个数,然后进行排序,将中间数作为枢纽值。 快速排序实现主框架: //快速排序 void QuickSort(int* arr, int left, int rig

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

6.1.数据结构-c/c++堆详解下篇(堆排序,TopK问题)

上篇:6.1.数据结构-c/c++模拟实现堆上篇(向下,上调整算法,建堆,增删数据)-CSDN博客 本章重点 1.使用堆来完成堆排序 2.使用堆解决TopK问题 目录 一.堆排序 1.1 思路 1.2 代码 1.3 简单测试 二.TopK问题 2.1 思路(求最小): 2.2 C语言代码(手写堆) 2.3 C++代码(使用优先级队列 priority_queue)

《数据结构(C语言版)第二版》第八章-排序(8.3-交换排序、8.4-选择排序)

8.3 交换排序 8.3.1 冒泡排序 【算法特点】 (1) 稳定排序。 (2) 可用于链式存储结构。 (3) 移动记录次数较多,算法平均时间性能比直接插入排序差。当初始记录无序,n较大时, 此算法不宜采用。 #include <stdio.h>#include <stdlib.h>#define MAXSIZE 26typedef int KeyType;typedef char In

Collection List Set Map的区别和联系

Collection List Set Map的区别和联系 这些都代表了Java中的集合,这里主要从其元素是否有序,是否可重复来进行区别记忆,以便恰当地使用,当然还存在同步方面的差异,见上一篇相关文章。 有序否 允许元素重复否 Collection 否 是 List 是 是 Set AbstractSet 否

Verybot之OpenCV应用一:安装与图像采集测试

在Verybot上安装OpenCV是很简单的,只需要执行:         sudo apt-get update         sudo apt-get install libopencv-dev         sudo apt-get install python-opencv         下面就对安装好的OpenCV进行一下测试,编写一个通过USB摄像头采