算法竞赛中树和图的数据结构表示

二叉树

定义性的二叉树表示:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

竞赛写法:
当每个结点是1~n并且不重复的数时,可以直接存树中每个结点的值,这样会简单一些,并且用0表示左孩子,1表示右孩子

 int tr[N][2];           //每个结点的左儿子结点编号存在tr[i][0],右儿子结点编号存在tr[i][1],若没有左儿子或者没有右儿子就存0或者-1
 tr[now][k ^ 1]]     //异或得到另一个儿子,如果当前儿子是左儿子0,异或后得到另一个儿子1

但是当树的编号比较稀疏的时候(不是1~n的时候)用这种方法就比较浪费空间,此时最好是用链表形式

多叉树和图

多叉树跟图很相似,可以用邻接矩阵或者邻接表来存储
邻接矩阵:
二维数组g[i][j] 表示i到j有一条边,
若是无权边,g[i][j]=1表示有边,g[i][j]=0表示无边
若是有权边,g[i][j]=权值,g[i][j]= -1 或者0表示无边
邻接表:
用数组或者vector数组度都行,个人比较喜欢用vector数组

const int N = 1e5 + 10; //结点编号范围10的5次方
const int M = 2 * N; //以有向图的格式存储无向图,所以每个节点至多对应2n-2条边

int h[N]; //邻接表存储树,有n个节点,所以需要n个队列头节点,其实就是存每个邻接表的第一个结点的编号(idx)
int e[M]; //存储结点里的元素值(1~n取值)
int ne[M]; //存储结点的next值(下一个结点编号)
int idx; //单链表指针,相当于每个结点的编号
int n; //题目所给的输入,n个节点
//a所对应的单链表中插入b,加入a->b边,头插法
void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
//遍历结点u的邻接表
for (int i = h[u]; i != -1; i = ne[i]) 
{
	int j=e[i];   //拿到结点值
}

vector数组表示法

vector<int> v[N];
//遍历
 for (int i = 0; i < v[u].size(); i ++ )
    {
        int t = v[u][i];
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值