基本数据结构模板

本文介绍了几种数据结构在处理图形和字符串问题中的应用:使用邻接表存储有向图,添加和遍历边;字符串哈希计算方法用于快速比较字符串;KMP模式匹配算法的ne数组构建;Trie树(字典树)实现字符串插入和搜索;以及二叉堆的插入、删除和调整操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.邻接表

用邻接表存储有向图

//加入有向边(x,y),权值为z
void add(int x,int y,int z)
{
    ver[++tot]=y,edge[tot]=z,ne[tot]=h[x],h[x]=tot;
}

//访问x出发的所有边 
for(int i=h[x];i;i=ne[i]){
    int y=ver[i],z=edge[i];
}

 2.字符串哈希

#define rep(i,a,b) for (register int i=a;i<b;++i)
#define per(i,a,b) for (register int i=a;i>b;--i)
typedef unsigned long long ULL;
const int N=1e6+10;
char s[N];
ULL f[N],p[N];
int h=13331; //h=131
ULL cal(int l,int r) //hash:s[l~r] 
{
	return f[r]-f[l-1]*p[r-l+1];
}
void init()
{
	p[0]=1;
	int len=strlen(s+1);
	rep(i,1,len+1){
		f[i]=f[i-1]*h+s[i]-'a'+1;
		p[i]=p[i-1]*h;
	}
}

3.kmp

ne数组

ne[1]=0;
int j=0;
rep(i,2,n+1){
	while(j>0&&a[i]!=a[j+1]) j=ne[j];
	if(a[i]==a[j+1]) ++j;
	ne[i]=j;
}

f数组 

int j=0;
rep(i,1,m+1){
	while(j>0&&(j==n||b[i]!=a[j+1])) j=ne[j];
	if(b[i]==a[j+1]) ++j;
	f[i]=j;
}

4.trie树

int tr[N][26],tot=1,cnt[M];
string s;
void ins()
{
	int p=1;
	for(auto i:s){
		int ch=i-'a';
		if(tr[p][ch]==0) tr[p][ch]=++tot;
		p=tr[p][ch];
	}
	++cnt[p];
}
int search()
{
	int p=1;
	for(auto i:s){
		int ch=i-'a';
		p=tr[p][ch];
		if(p==0) return 0;
	}
	return cnt[p];
}

5.二叉堆

int h[N],n;
void up(int p)
{
	while(p>1){
		if(h[p]>h[p/2]) swap(h[p],h[p/2]),p/=2;
		else break;
	}
}
void down(int p)
{
	int s=2*p;
	while(s<=n){
		if(s<n&&h[s]<h[s+1]) ++s;
		if(h[s]>h[p]) swap(h[s],h[p]),p=s,s=2*p;
		else break;
	}
}
void ins(int val)
{
	h[++n]=val;
	up(n);
}
void extract()
{
	h[1]=h[n--];
	down(1);
}
void remove(int k)
{
	h[k]=h[n--];
	up(k),down(k);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值