上一节我们讲了树和二叉树的概念了,在这一章我们用链式结构来实现二叉树.
准备数据
典型的二叉树的链式存储结构如下:
class ChainTreeType
{
char NodeData; //元素数据
ChainTreeType LSonNode; //左子树
ChainTreeType RSonNode; //右子树
}
ChainTreeType root = null; //根结点
有时候,为了后续计算的方便,也可以保存一个该结点的父结点的引用,此时二叉树的链式存储结构包含了结点元素,指向父结点的引用及分别指向左子树和右子树的引用,这种带父引用的链式存储结构代码如下:
class ChainTreeType
{
char NodeData; //元素数据
ChainTreeType LSonNode; //左子树
ChainTreeType RSonNode; //右子树
CharinTreeType ParentNode; //父结点引用
}
ChainTreeType root = null; //根结点
在这里我们使用上面的定义.
初始化二叉树
在使用二叉树之前,我们需要初始化二叉树,在程序中需要将一个结点设置为二叉树的根结点,代码如下:
public static CBTType InitTree(){
CBTType node;
if((node=new CBTType())!=null){ //申请内存
System.out.printf("请先定义根结点数据:\n");
node.data = input.next();
node.left = null; //设置左子树为空
node.right = null; //设置右子树为空
if (node!=null)
return node;
else
return null;
}
return node;
}
查找结点
查找结点即在二叉树中的每一个结点中,按个比较数据,当找到目标数据时将返回该数据所在结点的引用.
public static CBTType TreeFindNode(CBTType treeNode,String data){
CBTType ptr = null;
if(treeNode ==null){
return null;
}
if(treeNode.data.equals(data)){ //判断当前结点是不是
return treeNode;
}else {
if((ptr=TreeFindNode(treeNode.left,data))!=null){ //递归查找左子树里面有没有符合的
return ptr;
}else if((ptr=TreeFindNode(treeNode.right,data))!=null){ //递归查找右子树里面有没有符合的
return ptr;
}else{
return null;
}
}
}
添加结点
添加结点即在二叉树中添加结点数据,添加结点时,出了要输入结点数据外,还需要制定其父结点,以及添加的结点是作为左子树还是右子树,代码如下:
public static void AddTreeNode(CBTType treeNode){
CBTType pnode,parent;
String data = null;
int menusel = 0;
if((pnode=new CBTType())!=null){ //申请内存
System.out.printf("请输入二叉树结点数据:\n");
pnode.data = input.next();
pnode.left = null;
pnode.right = null;
System.out.printf("请输入父结点数据:\n");
data = input.next();
parent = TreeFindNode(treeNode,data); //查找制定数据的结点
if (parent ==null){ //如果没有找到
System.out.printf("未找到该父结点:\n");
pnode = null; //释放内存
return ;
}
System.out.printf("1.添加该结点到左子树 2.添加该结点到右子树 \n");
do {
menusel = input.nextInt(); //输入选择项,是添加左子树还是右子树
if(menusel==1||menusel==2){
if (parent ==null){
System.out.printf("未找到该父结点,请先设置父节点 \n");
}else{
switch (menusel){
case 1:
if (parent.left!=null){ //添加到左子树
System.out.printf("左子树不为空 \n");
}else {
parent.left = pnode;
}
break;
case 2:
if(parent.right!=null){ //添加到右子树
System.out.printf("右子树不为空 \n");
}else {
parent.right = pnode;
}
break;
default:
System.out.printf("无效参数 \n");
}
}
}
}while (menusel!=1 && menusel!=2);
}
}
获取左子树
public static CBTType TreeLeftNode(CBTType treeNode){
if(treeNode!=null){
return treeNode.left;
}
return null;
}
获取右子树
public static CBTType TreeRightNode(CBTType treeNode){
if(treeNode!=null){
return treeNode.right;
}
return null;
}
判断空树
public static boolean TreeIsEmpty(CBTType treeNode){
if(treeNode==null){
return true;
}
return false;
}
计算二叉树深度
计算二叉树深度即计算二叉树中结点的最大层数,这里往往需要采用递归算法来实现.
*/
public static int TreeDepth(CBTType treeNode){
int depthLeft,depthRight = 0;
if (treeNode ==null){
return 0;
}
depthLeft = TreeDepth(treeNode.left);
depthRight = TreeDepth(treeNode.right);
if(depthLeft>depthRight){
return depthLeft+1;
}else {
return depthRight+1;
}
}
清空二叉树
清空二叉树这里也需要用到递归算法来实现.
public static void ClearTree(CBTType treeNode){
if(treeNode!=null){
ClearTree(treeNode.left);
ClearTree(treeNode.right);
treeNode = null;
}
}
显示当前结点
public static String TreeNodeData(CBTType treeNode){
if(treeNode!=null){
System.out.printf("%s \n",treeNode.data);
return treeNode.data;
}
return "";
}
按层遍历
public static void LevelTree(CBTType treeNode){
CBTType p;
CBTType [] q = new CBTType[MAXLEN];
int head = 0;
int tail = 0;
if(treeNode!=null){
tail = (tail+1)%MAXLEN;
q[tail] = treeNode;
}
while (head!=tail){
head = (head+1)%MAXLEN;
p = q[head];
TreeNodeData(p);
if(p.left!=null){
tail = (tail+1)%MAXLEN;
q[tail] = p.left;
}
if(p.right!=null){
tail = (tail+1)%MAXLEN;
q[tail] =p.right;
}
}
}
先序遍历算法
public static void DLRTree(CBTType treeNode){
if(treeNode!=null){
TreeNodeData(treeNode);
DLRTree(treeNode.left);
DLRTree(treeNode.right);
}
}
中序遍历算法
public static void LDRTree(CBTType treeNode){
if(treeNode!=null){
LDRTree(treeNode.left);
TreeNodeData(treeNode);
LDRTree(treeNode.right);
}
}
后序遍历算法
public static void LRDTree(CBTType treeNode){
if(treeNode!=null){
LRDTree(treeNode.left);
LRDTree(treeNode.right);
TreeNodeData(treeNode);
}
}