单链表的实现
struct node{
int value;
node *pre,*next;
};
node *head,*tail;
void init()
{
head=new node();
tail=new node();
head->next=tail;
tail->pre=head;
}
void insert(node *p,int val)//在p后插入包含数据val的新节点
{
q=new node();
q->value=val;
p->next->pre=q;
q->next=p->next;
p->next=q;q->pre=p;
}
void remove(node *p)
{
p->pre->next=p->next;
p->next->pre=p->pre;
delete p;
}
void recycle()
{
while(head!=tail)
{
head=head->next;
delete head->pre;
}
delete tail;
}
数组模拟链表
struct node{
int value;
int pre,next;
}node[MAXSIZE];
int head,tail,tot;
int init()
{
tot=2;
head=1;tail=2;
node[head].next=tail;
node[tail].next=head;
}
void insert(int p,int val)
{
q=++tot;
node[q].value=val;
node[node[p].next].pre=q;
node[q].next=node[p].next;
node[p].next=q;
node[q].pre=p;
}
void remove(int p)
{
node[node[p].next].pre=node[p].pre;
node[node[p].pre].next=node[p].next;
}
void clear()
{
memset(node,0,sizeof(node));
head=tail=tot=0;
}
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n,a;
set<pair<int,int> >s;
int main()
{
cin>>n>>a;
s.insert({a,1});
for(int i=2;i<=n;++i)
{
cin>>a;
s.insert({a,i});
auto it=s.find({a,i});
pair<int,int>ans;
ans.first=0x3f3f3f3f;
if(++it!=s.end())
{
ans={(*it).first-a,(*it).second};
}it--;
if(it--!=s.begin()&&ans.first>=a-(*it).first)
{
ans={a-(*it).first,(*it).second};
}
cout<<ans.first<<' '<<ans.second<<endl;
}
}
set作为一个容器也是用来存储同一数据类型的数据类型,并且能从一个数据集合中取出数据,在set中每个元素的值都唯一,而且系统能根据元素的值自动进行排序。应该注意的是set中数元素的值不能直接被改变。C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,又称RB树(Red-Black Tree)。RB树的统计性能要好于一般平衡二叉树,所以被STL选择作为了关联容器的内部结构。
方便快速检索
lower_bound(key_value) ,返回第一个大于等于key_value的迭代器
upper_bound(key_value),返回最后一个大于等于key_value的迭代器
#include<bits/stdc++.h>
using namespace std;
const int N=1e4+10;
int n;
struct node{
int val;
int pre,next;
int id;
}a[N];
int loc[N];
vector<int>res;
bool cmp(node a,node b)
{
return a.val<b.val;
}
void remove(int x)
{
a[a[x].next].pre=a[x].pre;
a[a[x].pre].next=a[x].next;
}
void solve()
{
for(int i=1;i<=n;++i)
{
loc[a[i].id]=i;//标记原数组中第i个数在排序后数组中位置
a[i].pre=i-1;a[i].next=i+1;//对排序后链表进行标记
}
int mid=(1+n)>>1;
res.push_back(a[mid].val );//数组全部输入完成后的中位数,即需要输出的最后一位数,存入res数组
for(int i=n;i>1;i-=2)//从后往前推,依次删除,一次删两个
{
int p1=loc[i],p2=loc[i-1];
//i=n时表示原数组中的最后两位数在排好序数组中的下标,将其删去可找到输入这两位数之前数组的中位数,也即答案的倒数第二位数字
if(p1>p2) swap(p1,p2);//方便后续操作
if(p1>=mid) mid=a[mid].pre;//如果被删除的p1是中位数或者在中位数右边,由于p2>p1 所以中位数向左移
else if(p2<=mid) mid=a[mid].next;//如果被删除的p2是中位数或者在中位数左边,由于p2>p1 所以中位数向右移
//如果一左一右,那么中位数不变
res.push_back(a[mid].val);
remove(p1);remove(p2);//删除p1,p2
}int cot=0;
for(auto it=res.rbegin();it!=res.rend();it++)
{
printf("%d ",(*it));
++cot;
if(!(cot%10)) printf("\n");
}
if(cot%10) printf("\n");
}
int main()
{
int t;scanf("%d",&t);
while(t--)
{
memset(a,0,sizeof(a));
res.clear();
int id;scanf("%d%d",&id,&n);
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i].val);
a[i].id=i;//标记数组输入顺序
}
printf("%d %d\n",id,(n+1)/2);
sort(a+1,a+1+n,cmp);//对输入数组进行排序
solve();
}
}