数据结构-树
树的定义
树是由n(n>=0)个节点组成的有限集合 如果n=0,这是一颗空树;
如果n>0,这n个节点有且只能存在一个节点作为树的根节点(root)。
- 树的每一个节点可以有零个或者多个后继节点,但是有且只有一个前驱节点(根节点没有前驱节点),反映了数据元素之间的层次关系。
- 树中某个节点的子数的个数称为该节点的度,树中节点最大的度称为该树的度。
- 度不为0的节点称为非终端节点,为0 的节点称为叶子节点或者终端节点。
- 多个互不相交的树称为森林,将树的根节点删去就成了森林,将n颗树加上一个节点,他也变成了一颗树。
树的遍历
先根遍历
- 访问根节点
- 按照从左到右的顺序进行遍历每一颗子树
后根遍历
- 按照从左到右的顺序进行遍历每一颗子树
- 访问根节点
先根遍历
- 访问根节点
- 从上向下,从左到右的访问树中的每一个节点
树的存储方式
说到了树的定义,相信大家也在实际中用到过,下面介绍一种简单的双亲存储结构
双亲存储结构
双亲存储结构,一个简单的树的存储例子
java代码
public class Tree { //定义一个简单的树的 例子
int data; //记录自身的数据
int parent; //记录他的父节点的位置
public void setData(int data) {
this.data = data;
}
public void setParent(int parent) {
this.parent = parent;
}
public int getData() {
return data;
}
public int getParent() {
return parent;
}
}
Tree[] trees=new Tree[10];通过数组的形式进行操作,将他的父节点记录下来,形成一个简单的树
c/c++可以通过结构体的方式简单实现
孩子链的存储结构
public class Tree {
int data;
List<Tree> sons;
public void setData(int data) {
this.data = data;
}
public void addSons(Tree tree){
sons.add(tree);
}
public int getData() {
return data;
}
public List<Tree> getSons() {
return sons;
}
}
同样也可以通过实现链式存储的方式,如上 ,通过将孩子节点存储的方式进行存储。
孩子兄弟链的存储结构
public class Tree {
int data;
Tree son;
Tree brother;
public void setData(int data) {
this.data = data;
}
public void setBrother(Tree brother) {
this.brother = brother;
}
public void setSon(Tree son) {
this.son = son;
}
public int getData() {
return data;
}
public Tree getBrother() {
return brother;
}
public Tree getSon() {
return son;
}
}
相应的也可以通过在类中实现,兄弟接口和子接口的方式,只要有兄弟节点则将其存储在brother中,第一个子节点存储在son中也可以实现树的链接。
二叉树
二叉树,也就每一个节点至多只能有两个子节点的树。同样二叉树可以用过顺序存储方式,也可以通过链式存储,二叉树的标准存储方式节点结构如下:
public class Tree {
int data;
Tree lTree; //左节点
Tree rTree; //右节点
public void setData(int data) {
this.data = data;
}
public void setlTree(Tree lTree) {
this.lTree = lTree;
}
public void setrTree(Tree rTree) {
this.rTree = rTree;
}
public int getData() {
return data;
}
public Tree getlTree() {
return lTree;
}
public Tree getrTree() {
return rTree;
}
}
二叉树的遍历
public void findTreePreOrder(Tree tree){ //先序遍历
if(tree!=null){
System.out.print(tree.getData()+" ");
findTreePreOrder(tree.lTree);
findTreePreOrder(tree.rTree);
}
}
public void findTreeInOrder(Tree tree){ //中序遍历
if(tree!=null){
findTreePostOrder(tree.lTree);
System.out.print(tree.getData()+" ");
findTreePostOrder(tree.rTree);
}
}
public void findTreePostOrder(Tree tree){ //后序遍历
if(tree!=null){
findTreePostOrder(tree.lTree);
findTreePostOrder(tree.rTree);
System.out.print(tree.getData()+" ");
}
}
可以发现先序,中序和后序遍历,他们的区别都是在取值的时候位置发生了改变,当我们在不同的地方输出时候,就能达到不同的效果。