当前位置: 首页 > news >正文

数据结构-Trie、并查集、堆

Trie通常有两种写法,一种是竞赛常用的数组表示,另一种问更直观的结构体表示

数组:acwing835

void insert(string& str)
{
int curr = 0;
for (int i = 0; i < str.size(); i++)
{
if (!son[curr][str[i] - 'a'])
son[curr][str[i] - 'a'] = ++index; //一定是++index
curr = son[curr][str[i] - 'a'];
}
cnt[curr]++; //索引是curr不是index
}

int query(string& str)
{
int curr = 0;
for (int i = 0; i < str.size(); i++)
{
if (!son[curr][str[i] - 'a'])
return 0;
curr = son[curr][str[i] - 'a'];
}
return cnt[curr]; //索引是curr不是index
}

int main()
{
int n;
cin >> n;
while (n--)
{
char ch;
string str;
cin >> ch >> str;
if (ch == 'I')
insert(str);
else
cout << query(str) << endl;
}
return 0;
}

结构体

#define alpha 26

typedef struct treeNode
{
struct treeNode* children[alpha];
bool is_end;
}treenode;

treenode* createnode()
{
treenode* p = new treenode;
p->is_end = false;
for (int i = 0; i < alpha; i++)
{
p->children[i] = NULL;
}
return p;
}

void insertnode(treenode* root, const string str)
{
treenode* now = root;
for (int i = 0; i < str.size(); i++)
{
int index = str[i] - 'a';
if (now->children[index] == NULL)
{
now->children[index] = createnode();
}
now = now->children[index];
}
now->is_end = true;
}

bool findnode(treenode* root, const string str)
{
treenode* now = root;
for (int i = 0; i < str.size(); i++)
{
int index = str[i] - 'a';
if (now->children[index] == NULL)
{
return false;
}
now = now->children[index];
}
return now->is_end;
}

int main()
{
treenode* root = createnode();
insertnode(root, "apple");
if (findnode(root, "apple"))
cout << true;
else
cout << false;
return 0;
}

并查集

例题:acwing836

const int N = 100010;
int set[N];

int find(int num)
{
if (set[num] < 0)
return num;
return set[num] = find(set[num]);
}

void merge(int num1, int num2)
{
int f1 = find(num1);
int f2 = find(num2);
if (f1 == f2)
return;
if (set[f1] < set[f2])
set[f2] = f1;
else if (set[f1] > set[f2])
set[f1] = f2;
else
{
set[f2]--; //注意一定是高度增加在先!
set[f1] = f2;
}
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
set[i] = -1;
}
while (m--)
{
string str;
int a, b;
cin >> str >> a >> b;
if (str == "M")
merge(a, b);
else
cout << ((find(a) == find(b)) ? "Yes" : "No") << endl;
}
return 0;
}

堆排序:acwing838

const int N = 100010;
int heap[N];
int sz = 0;

void Swap(int a, int b)
{
swap(heap[a], heap[b]);
}

void up(int index)
{
int curr = index;
while (curr / 2 && heap[curr] < heap[curr / 2])
{
Swap(curr, curr / 2);
curr /= 2;
}
}

void insert(int num)
{
heap[++sz] = num;
up(sz);
}

void down(int index)
{
int curr = index;
if (index * 2 <= sz && heap[index * 2] < heap[curr]) //注意index和curr的使用
curr = index * 2;
if (index * 2 + 1 <= sz && heap[index * 2 + 1] < heap[curr])
curr = index * 2 + 1;
if (curr == index)
return;
Swap(curr, index);
down(curr);
}

int main()
{
int n, m;
cin >> n >> m;
for (int i = 0; i < n; i++)
{
int num;
cin >> num;
insert(num);
}
for (int i = 0; i < m; i++)
{
cout << heap[1] << ' ';
Swap(1, sz);
sz--;
down(1);
}
return 0;
}

模拟堆:acwing839

const int N = 100010;
int heap[N];
int h[N];
int p[N];
int pos = 0;
int sz = 0;

void Swap(int index1, int index2)
{
swap(h[p[index1]], h[p[index2]]); //三者的顺序需要注意
swap(heap[index1], heap[index2]);
swap(p[index1], p[index2]);
}

void up(int index)
{
int curr = index;
while (curr / 2 && heap[curr] < heap[curr / 2])
{
Swap(curr, curr / 2);
curr /= 2;
}
}

void down(int index)
{
int curr = index;
if (index * 2 <= sz && heap[index * 2] < heap[curr])
curr = index * 2;
if (index * 2 + 1 <= sz && heap[index * 2 + 1] < heap[curr])
curr = index * 2 + 1;
if (curr == index)
return;
Swap(curr, index);
down(curr); //down在交换下面,且需要down的索引是curr
}

void pop_min()
{
Swap(1, sz);
sz--;
down(1);
}

void pop(int index)
{
int curr = h[index];
Swap(curr, sz);
sz--;
up(curr);
down(curr);
}

void insert(int num)
{
heap[++sz] = num;
h[++pos] = sz;
p[sz] = pos;
up(sz);
}

void change(int index, int num)
{
heap[h[index]] = num;
up(h[index]);
down(h[index]);
}

int main()
{
int n;
cin >> n;
while (n--)
{
string str;
cin >> str;
if (str == "I")
{
int num;
cin >> num;
insert(num);
}
else if (str == "PM")
cout << heap[1] << endl;
else if (str == "DM")
pop_min();
else if (str == "D")
{
int index;
cin >> index;
pop(index);
}
else
{
int a, b;
cin >> a >> b;
change(a, b);
}
}
return 0;
}

http://www.jsqmd.com/news/1309681/

相关文章:

  • AI渠道归因不是算法竞赛,而是归因治理革命:3步完成数据血缘对齐、模型可观测性部署与业务侧可信交付
  • 深圳软件开发外包怎么选择靠谱团队
  • MQTT.js终极指南:5分钟快速掌握Node.js与浏览器端物联网消息传输
  • SpringBoot3+Vue3+MySQL 劳务外包管理系统源码 前后端分离实战项目
  • 微软Kiota CVE-2026-59865与CVE-2026-59864双响炮:恶意spec一把梭干穿API SDK生成器
  • 做企业数据库安全审计的公司有哪家?看看安得和众的这款产品吧
  • 上海GEO代运营选型指南:中小微高性价比方案对比 - 筑云鲸
  • 3分钟快速上手:Firefox专用Sketchfab模型下载终极指南
  • GESP C++二级X字矩阵编程题解析与实现
  • 2026 年新发布:迪庆有实力的钢结构工厂推荐,拆迁房的秘密:为什么它比混凝土更省钱? - 行业推荐官【认证】
  • AI云边协同性能瓶颈突破(2024边缘推理实测数据全公开)
  • 如何用遗传算法智能求解拼图:GAPS 5分钟完全指南 [特殊字符]
  • Wand-Enhancer终极指南:3步解锁WeMod完整功能,免费获得专业版体验
  • 单片机毕设项目:单片机驱动 LCD1602 的智能环境监测控制系统设计 基于 51 单片机继电器驱动的环境温湿度自动调节系统(017901)
  • 钙质土中重力锚水平承载力数值模拟与工程应用
  • 嵌入式传感器包设计:从模块化集成到智能感知中枢实践
  • 解决跨平台渐变难题:React Native Nike Running中LinearGradient组件适配方案
  • 标准换热器试验台与定制实验平台应该如何选择?
  • 终极Go代码质量检查指南:5步打造专业级开发工作流
  • Skeleton核心原理揭秘:CAGradientLayer滑动动画的底层实现
  • 免费开源的双屏PDF演示工具Pympress:让演讲更专业更轻松的终极指南
  • 如何通过Unitree ROS包实现四足机器人从仿真到实物的无缝控制
  • 原神自动化助手:3步解放双手,告别重复操作疲劳
  • 从PyTorch到LangChain,AI框架命名规范差异图谱(附自动校验CLI工具)
  • 仅限前200名获取:《AI游戏音效生产标准v2.1》——含12个可商用开源模型声学参数对照表与混音预设包
  • 如何用RedInk解决内容创作者的生产力困境:从创意到发布的AI全流程自动化
  • 打破技术壁垒!拖拽配置 LLM,业务 AI 智能体搭建门槛清零
  • Super Productivity:5个核心功能彻底改变你的时间管理方式
  • 数据血缘安全防护体系构建与实践
  • 从0到1搭建主题系统:SakuraKit架构设计与最佳实践