0x13链表与邻接表

单链表的实现

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;
 } 

136. 邻值查找

#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的迭代器

106. 动态中位数

#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(); 
		
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Dijkstra算法和邻接链表实现最短路径的示例代码: ```cpp #include <iostream> #include <vector> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; struct Edge { int to; int weight; Edge(int t, int w) : to(t), weight(w) {} }; vector<Edge> adj[100001]; // 邻接链表 int dist[100001]; // 最短路径长度 bool visited[100001]; // 是否访问过 void dijkstra(int start) { priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq; pq.push(make_pair(0, start)); dist[start] = 0; while (!pq.empty()) { int u = pq.top().second; pq.pop(); if (visited[u]) continue; visited[u] = true; for (int i = 0; i < adj[u].size(); i++) { int v = adj[u][i].to; int weight = adj[u][i].weight; if (!visited[v] && dist[v] > dist[u] + weight) { dist[v] = dist[u] + weight; pq.push(make_pair(dist[v], v)); } } } } int main() { int n, m, start; cin >> n >> m >> start; // 初始化 for (int i = 1; i <= n; i++) { dist[i] = INF; visited[i] = false; } // 读入边 for (int i = 0; i < m; i++) { int u, v, w; cin >> u >> v >> w; adj[u].push_back(Edge(v, w)); } // 计算最短路径 dijkstra(start); // 输出结果 for (int i = 1; i <= n; i++) { if (dist[i] == INF) cout << "INF" << endl; else cout << dist[i] << endl; } return 0; } ``` 在这个示例代码中,我们使用了邻接链表存储图,并且使用了一个优先队列来实现Dijkstra算法。在计算最短路径时,我们首先将源节点加入优先队列,并将其到源节点的距离设置为0。然后,我们不断取出队列中距离最小的节点,并更新与之相邻的节点的最短路径长度。最终,我们得到了所有节点到源节点的最短路径长度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值