版权声明: https://blog.csdn.net/Wang_Jiankun/article/details/82259797
数据结构与算法(C++)– 树(Tree)
1、树的基础知识
- 树(tree): 一些节点的集合,可以为空集
- 子树(sub tree): 树的子集
- 根(root): 树的第一个节点
- 孩子和父亲(Child and parent): 一条边的前一个节点为父亲,后一个节点为孩子
- 叶 (leaf): 没有孩子的节点
- 兄弟(sibling): 具有相同父亲的节点
- 路径和长度(Path and length): 任意两个能联通的节点间存在路径,这条路径上边的个数即为长度
- 深度和高(Depth and height): 从根到该节点的长度即为深度,从该节点到叶子节点的长度即为高度。一颗树的深度总是等于高度。
2、二叉树(Binary Tree )
定义: 每个节点都不能有多于两个的孩子
树的各种参数的关系:
- N个节点的二叉树的深度:最大(N-1), 最小(logN)
- 二叉树中深度为 i 的节点有几个:最多(2^i), 最少(1)
- 深度为 d 的二叉树有几个节点:最多(2^(d+1) - 1), 最少(d+1)
- 二叉树有 N0 个叶节点,N2 个两个孩子的节点,求关系:
- 节点数:N0 + N1 + N2 = N
- 边数:N1 + 2*N2 = N - 1
- 推出:N2 = N0 - 1
各种树:
- 完美二叉树(Perfect Binary Tree)
- 除了叶子节点,其它节点都有两个孩子
- 所有叶子节点都在同一层
- 每一层都达到其所能容纳的最大节点数
- 完全二叉树(Complete Binary Tree )
- 除了最后一层,其它每一层都达到其所能容纳的最大节点数
- 最后一层的所有节点都在左边
3、树的实现
// 孩子和兄弟
struct TreeNode
{
int data;
TreeNode *fistChild;
TreeNode *nextSibling;
};
// 左孩子和右孩子,只适用于二叉树
struct BinaryTree
{
int data;
BinaryTree *leftChild;
BinaryTree *rightChild;
};
4、树的遍历
创建树:
输入: 0 1 11 -1 -1 12 -1 123 -1 -1 2 -1 21 -1 -1
BinaryTree *CreatBiTree()
{
int data;
BinaryTree *T;
cin >> data;
if(data == -1)
T = NULL;
else
{
T = new BinaryTree;
T->data = data;
T->leftChild = CreatBiTree();
T->rightChild = CreatBiTree()
}
return T;
}
前序遍历(preorder traversal): 中左右
结果: R, T1, T11, T12, T123, T2, T21
void PreTravel(BinaryTree *tree)
{
if(tree)
{
cout << tree->data << " ";
PreTravel(tree->leftChild);
PreTravel(tree->rightChild);
}
}
中序遍历(Inorder Traversal): 左中右
结果: T11, T1, T12, T123, R, T2, T21
void InorderTravel(BinaryTree *tree)
{
if(tree)
{
InorderTravel(tree->leftChild);
cout << tree->data << " ";
InorderTravel(tree->rightChild);
}
}
后序遍历( Postorder Traversal ): 左右中
结果: T11, T123, T12, T1, T21, T2, R
void PostTravel(BinaryTree *tree)
{
if(tree)
{
PostTravel(tree->leftChild);
PostTravel(tree->rightChild);
cout << tree->data << " ";
}
}
层序遍历(Level-order Traversal):
结果: R, T1, T2, T11, T12, T21, T123