树是一种表达层级结构的数据结构,也是实现高效算法与数据结构的基础。
学习之前的基础:数组,循环处理,结构体,递归函数。
树:由结点(node)和连接结点的边(edge)构成。
一、树的相关基本概念:
双亲(父母/前件),子女(孩子/后件),双亲和子女的关系是相对而言的。
兄弟:若几个结点的双亲为同一个结点,则这些结点互称为兄弟。
祖先:将从树根到某一结点K的路径中,K前所经过的所有结点称为K的祖先。
子孙:以某结点K为根的子树中的任意一个结点都称为K的子孙。
结点的度:某一结点拥有的子女的个数。
树的度:树中所有结点的度的最大值。
叶子节点(终端节点):度为0的结点。
分支节点(非终端节点):度不为0的结点。
结点的层次:(有两种不同的说法,有的说根结点所在层次是0,有的说根结点所在层次是1)
树的深度(高度):树中结点的最大层次数。
在一棵树中,除了根节点外,其他任何结点有且仅有一个双亲,有0个或多个子女,他的子女恰巧为其子树的根结点。
二叉树:二叉树是一个由结点构成的有限集合,这个集合或者为空,或者由一个根结点及两棵互不相交的分别称作这个根结点的左子树和右子树的二叉树组成。
有序树:若树中任意结点的子树均看成是从左到右有次序的,不能随意交换,则称该树是有序树。
------------------------------------------------------------------------------------------
二叉树不是一般树形结构的特殊形式,它们是两种不同的数据结构
区别:
1、二叉树中每一个非空结点最多只有两个子女,而一般的树形结构中每个非空结点可以有0到多个结点。
2、二叉树中结点的子树要区分左子树和右子树,即使在结点只有一颗子树的情况下,也要明确指出是左子树还是右子树。
------------------------------------------------------------------------------------------
现学现用
1、Rooted Trees(有根树的表达)
https://vjudge.net/problem/Aizu-ALDS1_7_A
这题是对一棵树结点的相关信息进行输出,输入数据完成,则是一棵确定的树
关键是用什么方法存储一个结点的信息(结点序号,双亲结点的序号,深度,结点类型,所有子女序号)
这里使用的是:左子右兄弟表示法
该方法包含以下信息:1、结点的父结点。2、结点最左侧子结点。3、结点右侧紧邻的兄弟结点。
//左子右兄弟表示法
typedef struct
{
int parent;
int left;
int right;
}Node;
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 100000+10;
//左子右兄弟表示法
typedef struct
{
int parent;
int left;
int right;
}Node;
Node T[maxn];
int n;
int getdepth(int u)
{
int d=0;
while(T[u].parent!=-1)
{
u=T[u].parent;
d++;
}
return d;
}
void print(int u)
{
int i,c;
cout << "