一,二叉树(Binary tree)
二叉树
满二叉树、Full Binary Tree、Perfect Binary Tree
完全二叉树
二叉搜索树(BST)
最优二叉树(哈夫曼树)
最优二叉搜索树
平衡二叉树(AVL树)
二叉堆
线段树
树状数组
红黑树
二,多叉树
多叉树
字典树(Trie,前缀树)
基数树(radix tree)
二项树(binomial tree)
三,森林
并查集
二项堆
四,树的存储方式
树的存储方式,按照内存结构和索引方向,可以分为四种:
(1)动态分配节点,父亲节点中存有指向孩子节点的指针,只需要根节点就能找出所有节点
应用场景:大部分场景
(2)以结构体数组的形式存节点,父亲节点中存有孩子节点的下标,也只需要根节点即可
应用场景:完全二叉树,因为它满足节点n的父节点是节点n/2
(3)动态分配节点,每个节点存有指向父亲的指针
应用场景:暂时没想到
(4)以结构体数组的形式存节点,每个节点存有父亲的下标
应用场景:并查集
PS:这里说的结构体数组,在真正实现的时候也可能是2个甚至多个数组,通过id对应,在逻辑上和结构体数组是一样的。
五,孩子兄弟表示法
任何一棵树,都可以通过孩子兄弟表示法,转化成一颗二叉树。
力扣 431. 将 N 叉树编码为二叉树
设计一个算法,可以将 N 叉树编码为二叉树,并能将该二叉树解码为原 N 叉树。一个 N 叉树是指每个节点都有不超过 N 个孩子节点的有根树。类似地,一个二叉树是指每个节点都有不超过 2 个孩子节点的有根树。你的编码 / 解码的算法的实现没有限制,你只需要保证一个 N 叉树可以编码为二叉树且该二叉树可以解码回原始 N 叉树即可。
例如,你可以将下面的 3-叉 树以该种方式编码:
图不重要,略
注意,上面的方法仅仅是一个例子,可能可行也可能不可行。你没有必要遵循这种形式转化,你可以自己创造和实现不同的方法。
注意:
N 的范围在 [1, 1000]
不要使用类成员 / 全局变量 / 静态变量来存储状态。你的编码和解码算法应是无状态的。
思路:
这题有很多思路,我的思路就是左孩子右兄弟表示法。
class Codec {
public:
// Encodes an n-ary tree to a binary tree.
TreeNode* encode(Node* root) {
if(!root)return NULL;
TreeNode*q,*q0=NULL;
for(int i=0;i<root->children.size();i++){
TreeNode*p=encode(root->children[i]);
if(i)q->right=p;
else q0=p;
q=p;
}
q=new TreeNode(1);
q->left=q0,q->right=NULL,q->val=root->val;
return q;
}
// Decodes your binary tree to an n-ary tree.
Node* decode(TreeNode* root) {
if(!root)return NULL;
TreeNode*p=root->left;
Node*ans=new Node(1);
ans->children.clear();
while(p){
ans->children.push_back(decode(p));
p=p->right;
}
ans->val=root->val;
return ans;
}
};