[PTA刷题]Reversing Linked List

Given a constant KK and a singly linked list LL, you are supposed to reverse the links of every KK elements on LL. For example, given LL being 1→2→3→4→5→6, if K = 3K=3, then you must output 3→2→1→6→5→4; if K = 4K=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 NN (\le 10^5105) which is the total number of nodes, and a positive KK (\le NN) 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 NN 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和后面的链表的元素个数并不一定相等。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值