二叉树
在树结构中,二叉树是最简单的一种形式。我们在研究树结构的时候,二叉树是重点。因为二叉树的描述相对简单,处理也相对简单。而且更为重要的是任意的树都可以转化为对应的二叉树。因此,二叉树是所有树结构的基础。
什么是二叉树
二叉树是树的一种特殊形式,其是n个节点的集合,每个节点最多有两个子节点。二叉树的子树仍然是二叉树。二叉树的一个节点对应的两个子树分别称为左子树和右子树。由于子树有左右之分,所以二叉树为有序树。
下面直接用代码展示二叉树的表示
1.准备数据
首先需要准备数据,也就是准备在二叉树结构操作中需要用到的变量及类。实例代码如下:
static final int MAXLEN=20; //最大长度
class TreeNode{ //定义二叉树节点类型
String data; //元素数据
TreeNode left; //左子树节点引用
TreeNode right; //右子树节点引用
}
这里定义了二叉树结构的类为TreeNode。节点的具体数据在data中,而引用left来指向左子树节点,right指向右子树节点。
2.初始化二叉树
在使用顺序表之前,首先要初始化二叉树。这里只需要将一个节点设置为二叉树的根节点。代码如下:
public static TreeNode initTree() {
TreeNode node=null;
if ((node=new TreeNode())!= null) { // 为根节点申请内存
System.out.println("请输入根结点数据");
node.data = sca.next();
node.left = null;
node.right = null;
if (node != null) {
return node;
} else {
return null;
}
}
return null;
}
这里首先申请内存,然后由用户输入一个根节点数据,并将指向左右子树的引用设置为空,即可完成二叉树初始工作。
3.添加节点
添加节点就是在二叉树中添加节点数据。添加节点时除了要输入节点数据外,还需要指定其父节点,以及添加节点是作为左子树还是右子树。
添加节点代码如下:
public static void addTreeNode(TreeNode genNode) {
TreeNode pnode=null;
TreeNode parent=new TreeNode();
String data;
int choose;
if ((pnode=new TreeNode())!= null) {// 为子节点分配内存
pnode.left = null;
pnode.right = null;
System.out.println("输入父节点的数据:");
data = sca.next();
parent = findTreeNode(genNode, data);
if (parent == null) {
System.out.println("未找到该父节点!");
pnode = null; // 释放节点内存
return;
} else {
System.out.println("1.将节点添加至左子树。2.将节点添加至右子树。");
do {
choose=sca.nextInt();
switch (choose) {
case 1:
if (parent.left == null) {
parent.left = pnode;
} else {
System.out.println("左子树不为空");
}
break;
case 2:
if (parent.right == null) {
parent.right = pnode;
} else {
System.out.println("右子树为空");
}
break;
default:
System.out.println("无效参数");
}
System.out.println("请输入子节点数据:");
pnode.data = sca.next();
} while (choose != 1 && choose != 2);
}
}
}
4.查找节点
查找节点就是遍历二叉树中的每一个节点,逐个比较数据,当找到目标数据时返回该数据所在节点的引用,代码如下:
public static TreeNode findTreeNode(TreeNode genNode, String data) {
TreeNode ptr;
if (genNode == null) {
return null;
} else {
if (genNode.data.equals(data)) {
return genNode;
} else { //分别向左右子树递归查找
if ((ptr = findTreeNode(genNode.left, data)) != null) {
return ptr;
} else if ((ptr = findTreeNode(genNode.right, data)) != null) {
return ptr;
} else {
return null;
}
}
}
}
5.计算二叉树深度
计算二叉树深度就是计算二叉树中节点的最大层数,这里往往采用递归算法来实现。代码如下:
public static int getTreeDepth(TreeNode genNode){
int depLeft,depRight;
if(genNode==null){
return 0;
}else{
depLeft=getTreeDepth(genNode.left);//左子树深度(递归调用)
depRight=getTreeDepth(genNode.right);//右子树深度(递归调用)
if(depLeft>depRight){
return depLeft+1;
}else {
return depRight+1;
}
}
}
6.按层遍历二叉树
按层遍历二叉树是最直观的遍历算法。首先处理第一层即根节点,在处理第一层根节点的左右子树,也即第二层,…….就是这样循环处理,就可以逐层遍历。代码如下:
public static void LevelTree(Node genNode){
Node p;
Node[] q=new Node[MAXSIZE]; //定义一个顺序栈
int head=0,tail=0;
if(genNode!=null){ //如果队首引用不为空
tail=(tail+1)%MAXSIZE; //计算循环队列队尾序号
q[tail]=genNode;
}
while(head!=tail){ //队列不为空进行循环
head=(head+1)%MAXSIZE;
p=q[head];
System.out.println(p.data);
if(p.left!=null){
tail=(tail+1)%MAXSIZE;
q[tail]=p.left;
}
if(p.right!=null){
tail=(tail+1)%MAXSIZE;
q[tail]=p.right;
}
}
}
7.先序遍历二叉树
先序遍历二叉树就是先访问根节点,再访问左子树,再访问右子树。程序中可以按照递归的思路来遍历二叉树。代码如下:
public static void DLRTree(TreeNode genNode){
if(genNode!=null){
System.out.println(genNode.data);
DLRTree(genNode.left);
DLRTree(genNode.right);
}
}
8.中序遍历二叉树
中序遍历二叉树就是先访问左子树节点,再访问根节点,再访问右子树节点。程序中可以按照递归的思路来遍历二叉树。代码如下:
public static void LDRTree(TreeNode genNode){
if(genNode!=null){
LDRTree(genNode.left);
System.out.println(genNode.data);
LDRTree(genNode.right);
}
}
9.后序遍历二叉树
后序遍历二叉树就是先访问左子树,再访问右子树,最后访问根节点。程序中可以按照递归的思路来遍历二叉树。代码如下:
public static void RDLTree(TreeNode genNode){
if(genNode!=null){
RDLTree(genNode.left);
RDLTree(genNode.right);
System.out.println(genNode.data);
}
}
好了,简单的介绍完了二叉树的java实现.