给定一个单链表 L1→L2→⋯→Ln−1→Ln,请编写程序将链表重新排列为 Ln→L1→Ln−1→L2→⋯。例如:给定L为1→2→3→4→5→6,则输出应该为6→1→5→2→4→3。
输入格式:
每个输入包含1个测试用例。每个测试用例第1行给出第1个结点的地址和结点总个数,即正整数N (≤105)。结点的地址是5位非负整数,NULL地址用−1表示。
接下来有N行,每行格式为:
Address Data Next
其中Address
是结点地址;Data
是该结点保存的数据,为不超过105的正整数;Next
是下一结点的地址。题目保证给出的链表上至少有两个结点。
输出格式:
对每个测试用例,顺序输出重排后的结果链表,其上每个结点占一行,格式与输入相同。
#include <iostream>
#include <list>
#include <vector>
#include <string>
#include <set>
using namespace std;
struct triple
{
triple(string Address, int Data = 0, string Next = "0")
:_Address(Address)
,_Data(Data)
,_Next(Next)
{}
triple()
{}
bool operator==(triple t)
{
if (t._Address == _Address)
{
return true;
}
else{
return false;
}
}
string _Address;
int _Data;
string _Next;
};
class MyComepare
{
public:
bool operator()(triple t1, triple t2)
{
if (t1._Address > t2._Address)
{
return true;
}
else
{
return false;
}
}
};
void fill_vector(vector<triple>& v, int num)
{
string Address;
int Data = 0;
string Next;
while (num != 0)
{
cin >> Address;
scanf("%d", &Data);
cin >> Next;
v.push_back(triple(Address, Data, Next));
num--;
}
}
void tidy_vector(vector<triple>& v, string& pfirst)
{
if (pfirst == "-1")
{
return;
}
set<triple, MyComepare> s(v.begin(), v.end());
int size = v.size();
for (int i = 0; i < size; i++)
{
// 此方法时间复杂度为nlogn
if (i == 0)
{
auto it = s.find(pfirst);
v[i] = *it;
}
else if (v[i-1]._Next == "-1")
{
v.resize(i);
return;
}
else{
auto it = s.find(v[i-1]._Next);
v[i] = *it;
}
/*此方法时间复杂度为N的平方
for (int j = i; j < size; j++)
{
if (i == 0)
{
if (v[j]._Address == pfirst)
{
swap(v[j], v[0]);
break;
}
}
else if (v[i-1]._Next == "-1")
{
v.resize(i);
return;
}
else
{
if (v[j]._Address == v[i-1]._Next)
{
swap(v[j], v[i]);
break;
}
}*/
}
}
list<triple> resort_vector(vector<triple>& v)
{
int size = v.size();
auto end = v.end();
auto begin = v.begin();
auto half = begin;
for (int i = 0; i < size/2; i++)
{
half++;
}
list<triple> ls(begin, half);
auto cur = ls.begin();
half--;
end--;
while (half != end)
{
ls.insert(cur, *end);
end--;
cur++;
}
auto next = ls.begin();
cur = next++;
while (cur != ls.end())
{
if (next == ls.end())
{
cur->_Next = "-1";
cur++;
break;
}
cur->_Next = next->_Address;
cur++;
next++;
}
return ls;
}
void print_list(list<triple>& ls)
{
for (auto& e : ls)
{
cout << e._Address << ' ' << e._Data << ' ' << e._Next << endl;
}
}
int main()
{
vector<triple> v;
string pfirst;
int num = 0;
cin >> pfirst;
scanf("%d", &num);
fill_vector(v, num);
tidy_vector(v, pfirst);
auto ls = resort_vector(v);
print_list(ls);
return 0;
}