[链表]邻值查找

最近c语言也刚学指针嘛所以想写写指针链表练练手qaq
首先,链表和数组相比,(那我还是感觉我们数组np(bushi))
最大的优势在于可以方便地实现“删除”操作,而劣势是随机访问不方便,只适合按照一定的顺序读取。
对于这个问题,我们考察每个数的时候只需要它的前驱和后继,而且考察的区间每次会多一个元素,这个性质可以转换为从完整的序列开始每次删去一个元素
显然,我们构造一个从小到大排序的链表就解决了

#include <iostream>
#include <algorithm>
#define data first
#define id second
using namespace std;
const int maxn = 2e5 + 10;
const int inf = 1e10 + 10;

pair<int, int> a[maxn], ans[maxn];
int n;

struct Node {
  int val;
  int idx;
  Node *prev, *next;
};
Node *head, *tail, *p[maxn];

void initialize() {
  head = new Node();
  tail = new Node();
  head -> next = tail;
  tail -> prev = head;
}

void insert(Node *p, int val, int idx) {
  Node *q = new Node();
  q -> val = val;
  q -> idx = idx;
  //先后再前
  p -> next -> prev = q;
  q -> next = p -> next;
  p -> next = q; q -> prev = p;
}

void remove(Node *p) {
  p -> next -> prev = p -> prev;
  p -> prev -> next = p -> next;
  delete p;
}

void recycle(Node *p) {
  while (head != tail) {
    head = head -> next;
    delete head -> prev;
  }
  delete p;
}

int main() 
{
  initialize();
  scanf("%d", &n);
	for (int i = 0; i < n; i++) 
    scanf("%d", &a[i].data), a[i].id = i;
	sort(a, a + n);

  Node *t = head;
  for (int i = 0; i < n; i++) {
    insert(t, a[i].data, a[i].id);
    t = t -> next;
    p[a[i].id] = t;
  }
  head -> val = tail -> val = inf;

  for (int i = n - 1; i > 0; i--) {
    int l = p[i] -> prev -> val, r = p[i] -> next -> val, m = p[i] -> val;
    if (abs(m - l) != abs(r - m)) {
			if (abs(m - l) < abs(r - m)) ans[i] = make_pair(abs(m - l), p[i] -> prev -> idx);
			else ans[i] = make_pair(abs(r - m), p[i] -> next -> idx);
		}
    else ans[i] = make_pair(m - l, l < m ? p[i] -> prev -> idx : p[i] -> next -> idx);
    remove(p[i]);
  }
  
  for (int i = 1; i < n; i++)
    printf("%d %d\n", ans[i].first, ans[i].second + 1);
  return 0;
}


posted @ 2021-11-01 20:13  _vv123  阅读(76)  评论(0编辑  收藏  举报