有 n 辆自行车依次来到停车棚,除了第一辆自行车外,每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或右边。(e.g.停车棚里已经有 3 辆自行车,从左到右编号为:3,5,1。现在编号为 2 的第 4 辆自行车要停在 5 号自行车的左边,所以现在停车棚里的自行车编号是:3,2,5,1)。给定n辆自行车的停放情况,按顺序输出最后停车棚里的自行车编号。n≤100000。
方法一:使用STL list
#include <bits/stdc++.h>
using namespace std;
long long n,x,a,b,c;
list<int>::iterator loc[100003]; //小技巧
int main(){
long long i;
list<int> L; //链表
scanf("%ld %ld",&n,&x);
L.push_back(x); //插入刚开始编号
loc[x] = L.begin(); //迭代器地址存入数组
list<int>::iterator temp; //临时迭代器
for(i=1;i<=n-1;i++){
cin>>a>>b>>c; //a为待插元素编号 b为表中元素编号 c表示左右
temp = loc[b];
if(c==0){
L.insert(temp,a);
//L.insert函数表示在链表L的temp位置前插入元素a
loc[a] = --temp; //将新插入的元素地址记录到数组中
}
else{
L.insert(++temp,a);
loc[a] = --temp;
}
}
for(list<int>::iterator it=L.begin();it!=L.end();it++)
cout<<*it<<" ";
return 0;
}
方法二:双向链表
#include <bits/stdc++.h>
using namespace std;
const int N = 200010;
struct node{ //双向链表
//int id; //结点编号,没用到
int data; //数据
int preid; //前一个结点
int nextid; //后一个结点
}nodes[N];
int now;
int locate[N]; //locate(x) = now; 值为x的结点位置在nodes[now]
void init() {
nodes[0].nextid = 1;
nodes[1].preid = 0;
now = 2;
}
void insert(int k, int x) { //插入一个nodes[now],插到nodes[k]的右面
nodes[now].data = x;
locate[x] = now; //记录值为x的结点的位置
nodes[now].nextid = nodes[k].nextid;
nodes[now].preid = k;
nodes[nodes[k].nextid].preid = now;
nodes[k].nextid = now;
now++;
}
int main() {
int n; cin >> n;
init();
int a; cin >> a; //第一辆车编号
insert(0, a);
n--;
while (n--) {
int x, y, z; cin >> x >> y >> z;
if (z == 0) //把x插到y的左边
insert(nodes[locate[y]].preid, x); //用locate[]快速定位
else //把x插到y的右边
insert(locate[y], x);
}
for (int i = nodes[0].nextid; i != 1; i = nodes[i].nextid)
cout << nodes[i].data << " ";
return 0;
}