树:有且仅有一个特定的称为根的结点。当结点数量大于1时,除根结点外其余结点被分割互不相交的集合,其中每个集合又是一棵数,并称为这个结点的子树。
个人理解:
怎么理解这段话的意思?就是说当有n个结点的时候,首先n个结点是个集合,但需要存在根结点p。该结点会将数字分割成2个集合,如果要满足树的定义,则这2个集合互不相交。(此时只是根结点分割后能满足树的定义)。分割成{a1,a2}集合后a1集合又可以按照根结点一样在分割(其a1集合又必须满足树的定义)。而a1称为根结点p的子树
层:树从根节点往下,层依次为1,2,3….。
度:该节点下面的直接子树个数总和。
叶子结点(终端结点):度为0的结点。
分支结点(非终端结点):度不为0的结点,很明显就是跟。
不多bb,下面直接具体说二叉树的实现
如果我们的二叉树是这样一棵树。要实现数据结构的存储该咋办呢?
首先了解下“扩展二叉树”的定义
扩展二叉树:二叉树的每个结点的空指针都引出一个虚节点,其值为特定值,如使用“#”表示其为空。
更具扩展二叉树的规则,则有如下树结构
前序遍历顺序为:a->#->b->c->#->#->#。
想想为什么使用扩展二叉树呢?
- 扩展二叉树通过前序遍历的顺序可以直接确定树的结构,不在需要中序遍历顺序。
二叉树的构造具体实现
使用链表结构存储结点,以及结点关系
public class Test {
public static void main(String[] args) throws Exception {
//必须是扩展二叉树的格式的前序遍历
TwoXTree tree=new TwoXTree(new Object[]{"a",'#',"b",'c','#','#','#'});
TwoXTreeNode node= tree.getTree();
System.out.println(node);
}
}
/**
* 二叉树结点
* <p>(二叉树结点和孩子兄弟表示法不同,孩子兄弟表示法中的结点使用的是前驱表示第一个孩子结点。后继表示该孩子结点的兄弟,并且树不存在左右之分,左右之分是针对2x树)
* @author name:zf Email:623039066@qq.com
*/
class TwoXTreeNode{
private TwoXTreeNode left;
private TwoXTreeNode right;
private Object data;
public TwoXTreeNode getLeft() {
return left;
}
public void setLeft(TwoXTreeNode left) {
this.left = left;
}
public TwoXTreeNode getRight() {
return right;
}
public void setRight(TwoXTreeNode right) {
this.right = right;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
class TwoXTree{
private TwoXTreeNode twoXTree;
private int index;
/**
* 构造二叉树
* @param preOrder 遵循扩展二叉树的前序遍历二叉树顺序的数据数组
* @throws Exception
*/
public TwoXTree(Object[] preOrder) throws Exception {
super();
if(preOrder==null || preOrder.length==0){
throw new Exception("前序遍历顺序不正确,请重新检查。");
}
index=0;
this.twoXTree=init(preOrder);
}
private TwoXTreeNode init(Object[] preOrder){
Object o= preOrder[index++];
if(o instanceof Character && (char)o=='#'){
return null;
}else{
TwoXTreeNode node=new TwoXTreeNode();
node.setData(o);
node.setLeft(init(preOrder));
node.setRight(init(preOrder));
return node;
}
}
public TwoXTreeNode getTree(){
return this.twoXTree;
}
}
通过debug模式即可看到树结构的正确性。
多维数组的存储
/**
* 演示多维数组存储
* @author name:zf Email:623039066@qq.com
*/
class ManyDimensionArray{
private Object [] manyDimensionArray;
private int p;
private int[] dimension;
//使用new ManyDimensionArray(2,5) 及等价于new object[2][5];
public ManyDimensionArray(int... dimension) {
super();
int length=1,q=0;
this.dimension=new int[dimension.length];
for(int i : dimension){
this.dimension[q++]=i;
length=length*i;
}
manyDimensionArray=new Object[length];
p=0;
}
public void init(Object ... objects){
for(Object o : objects){
manyDimensionArray[p++]=o;
}
}
public Object[] getArray(){
return this.manyDimensionArray;
}
}