Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5→6.
Input Specification:
Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤105) which is the total number of nodes, and a positive K (≤N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.
Then N lines follow, each describes a node in the format:
Address Data Next
where Address
is the position of the node, Data
is an integer, and Next
is the position of the next node.
Output Specification:
For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.
Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX_ADDRESS_SIZE 100000
struct Rnode{
int address=-1;
int data=0;
int next=-1;
};
void reverse_linked_nodes(vector<Rnode>& list, int start, int count);
int main()
{
int head_add,count,reverse_count;
int nadd,ndata,nnext;
cin >> head_add >> count >> reverse_count;
vector<Rnode> list(MAX_ADDRESS_SIZE);
for(int i=0;i<count;i++){
cin >> nadd >> ndata >> nnext;
list[nadd].address=nadd;
list[nadd].data=ndata;
list[nadd].next=nnext;
}
vector<Rnode> node_list;
node_list.push_back(list[head_add]);
while(node_list.back().next!=-1){
node_list.push_back(list[node_list.back().next]);
}
int reverse_times = (int)node_list.size() / reverse_count;
//看我看我。这里不可以认为count等同于node_list.size() 哦。不可以用count作为后面的链表长度。
for(int i=0; i<reverse_times; i++)
{
int start = i*reverse_count;
reverse_linked_nodes(node_list, start,reverse_count );
}
// output result
for (int i = 0; i < node_list.size()-1; i++)
{
printf("%05d %d %05d\n", node_list[i].address, node_list[i].data, node_list[i+1].address);
}
printf("%05d %d %d", node_list.back().address, node_list.back().data, -1);
return 0;
}
void reverse_linked_nodes(vector<Rnode>& list, int start, int count)
{
vector<Rnode> myRlist;
for(int i=0;i<count;i++){
myRlist.push_back(list[start+i]);
}
reverse(myRlist.begin(), myRlist.end());
for(int i=0;i<count;i++){
list[start+i]=myRlist[i];
}
}
------------总结-------------
1、Vector的使用。
vector(向量): C++中的一种数据结构,确切的说是一个类.它相当于一个动态的数组,当程序员无法知道自己需要的数组的规模多大时,用其来解决问题可以达到最大节约空间的目的.
基本操作:
(1)头文件#include<vector>.
(2)创建vector对象,vector<int> vec;
(3)尾部插入数字:vec.push_back(a);
(4)使用下标访问元素,cout<<vec[0]<<endl;记住下标是从0开始的。
(5)使用迭代器访问元素.
vector<int>::iterator it; for(it=vec.begin();it!=vec.end();it++) cout<<*it<<endl;
(6)插入元素: vec.insert(vec.begin()+i,a);在第i+1个元素前面插入a;
(7)删除元素: vec.erase(vec.begin()+2);删除第3个元素
vec.erase(vec.begin()+i,vec.end()+j);删除区间[i,j-1];区间从0开始
(8)向量大小:vec.size();
(9)清空:vec.clear();
vector的元素不仅仅可以使int,double,string,还可以是结构体,但是要注意:结构体要定义为全局的。
算法
(1) 使用reverse将元素翻转:需要头文件#include<algorithm>reverse(vec.begin(),vec.end());将元素翻转(在vector中,如果一个函数中需要两个迭代器,一般后一个都不包含.)(2)使用sort排序:需要头文件#include<algorithm>,sort(vec.begin(),vec.end());(默认是按升序排列,即从小到大).
可以通过重写排序比较函数按照降序比较,如下:
定义排序比较函数:
bool Comp(const int &a,const int &b)
{
return a>b;
}
调用时:sort(vec.begin(),vec.end(),Comp),这样就降序排序。
vector<Rnode> list(MAX_ADDRESS_SIZE);
关于给出大小。
不明确给出的话,就默认大小是0,我不可以 list[15]这样子去访问。可以push_back这些,但是和数组一样不能下标越界。
push_back了以后 它的大小就动态变大了。
因为向量还是连续的内存空间,即使你输入数据只有一个9999的地址,你也得开辟10000的空间,跟你一开始就指定10000的空间没差。
2、“有多余结点不在链表上“
意思是,我输入N个结点,但不是说这N个结点都在这个链表上。其中几个有可能是游离的(地址并不相连)。
所以一开始的count和后面的链表的元素个数并不一定相等。