实现二叉树的常用操作算法:
包括二叉树的建立、遍历、求高度、线索化等操作
package tree;
public class Tree<T> {
private treeNode<T> pre ; //线索化时记录前一个节点
public treeNode<T> root; //根节点
//声明节点
static class treeNode<T> {
//节点对应存储的数据
T value;
//表示左右孩子的指针是否为线索,默认是false,非线索
boolean left = false;
boolean right = false;
//左右孩子的指针,此处用的引用
treeNode<T> leftChild;
treeNode<T> rightChild;
treeNode(T value){
this.value = value;
}
}
public Tree (T array[],int index){
root = createTree(array,index);
}
//首先创树
public <T> treeNode createTree(T array[],int index){
treeNode<T> root = null;
if(index < array.length) {
root = new treeNode(array[index]);
root.leftChild = createTree(array, index * 2 + 1);
root.rightChild = createTree(array, index * 2 + 2);
}
return root;
}
public void preTravel(){
preOrderTravel(root);
System.out.println("前序遍历");
}
public void midTravel(){
midOrderTravel(root);
System.out.println("中序遍历");
}
public void aftTravel(){
aftOrderTravel(root);
System.out.println("后序遍历");
}
//前序遍历
public <T> void preOrderTravel(treeNode<T> root){
if (root == null){
return;
}else{
//前中后遍历其实也就是这下面三行的顺序不同
System.out.print(root.value+" ,");
preOrderTravel(root.leftChild);
preOrderTravel(root.rightChild);
}
}
//中序遍历
public <T> void midOrderTravel(treeNode<T> root){
if (root == null){
return;
}else{
//前中后遍历其实也就是这下面三行的顺序不同
midOrderTravel(root.leftChild);
System.out.print(root.value+" ,");
midOrderTravel(root.rightChild);
}
}
//后序遍历
public <T> void aftOrderTravel(treeNode<T> root){
if (root == null){
return;
}else{
//前中后遍历其实也就是这下面三行的顺序不同
aftOrderTravel(root.leftChild);
aftOrderTravel(root.rightChild);
System.out.print(root.value+" ,");
}
}
public void high(){
System.out.println("树的高度为"+depth(root));
}
//get树的深度
public <T> int depth(treeNode<T> root){
if(root == null){
return 0;
}
//返还左子树和右子树最深的那个,然后加上自己的根节点
return Math.max(depth(root.leftChild) + 1,depth(root.rightChild) + 1);
}
//前序线索化二叉树并且遍历
public void preThread(){
preThreadOrder(root);
preThreadList(root);
}
void preThreadList(treeNode<T> node) {
while(node != null) {
while(!node.left) {
System.out.print(node.value + ", ");
node = node.leftChild;
}
System.out.print(node.value + ", ");
node = node.rightChild;
}
}
public void preThreadOrder(treeNode<T> node){
if(node!=null){
//左指针为空时,让他指向pre的元素
if(node.leftChild==null){
node.leftChild = pre;
node.left=true;
}
//前一个节点的后继节点指向当前节点
if(pre != null && pre.rightChild == null) {
pre.rightChild = node;
pre.right = true;
}
pre = node;
//处理左子树
if(!node.left) {
preThreadOrder(node.leftChild);
}
//处理右子树
if(!node.right) {
preThreadOrder(node.rightChild);
}
}
}
//中序线索化二叉树并且遍历
public void midThread(){
inThreadOrder(root);
inThreadList(root);
inPreThreadList(root);
}
//中序线索化二叉树
void inThreadOrder(treeNode node) {
if (node == null) {
return;
}
//处理左子树
inThreadOrder(node.leftChild);
//左指针为空,将左指针指向前驱节点
if (node.leftChild == null) {
node.leftChild = pre;
node.left = true;
}
//前一个节点的后继节点指向当前节点
if (pre != null && pre.rightChild == null) {
pre.rightChild = node;
pre.right = true;
}
pre = node;
//处理右子树
inThreadOrder(node.rightChild);
}
void inThreadList(treeNode node) {
//1、找中序遍历方式开始的节点
while(node != null && !node.left) {
node = node.leftChild;
}
while(node != null) {
System.out.print(node.value + ", ");
//如果右指针是线索
if(node.right) {
node = node.rightChild;
} else { //如果右指针不是线索,找到右子树开始的节点
node = node.rightChild;
while(node != null && !node.left) {
node = node.leftChild;
}
}
}
}
/**
* 中序遍历线索二叉树,按照前驱方式遍历(思路:找到最右子节点开始倒序遍历)
* @param node
*/
void inPreThreadList(treeNode node) {
//1、找最后一个节点
while(node.rightChild != null && !node.right) {
node = node.rightChild;
}
while(node != null) {
System.out.print(node.value + ", ");
//如果左指针是线索
if(node.left) {
node = node.leftChild;
} else { //如果左指针不是线索,找到左子树开始的节点
node = node.leftChild;
while(node.rightChild != null && !node.right) {
node = node.rightChild;
}
}
}
}
public static void main(String[] args){
Integer a[] ={1,2,3,4,5,6,7};
//使用数组创建二叉树
Tree<Integer> tree = new Tree<Integer>(a,0);
//前序遍历
tree.preTravel();
tree.midTravel();
tree.aftTravel();
//求高度
tree.high();
//线索化
//tree.preThread();
tree.midThread();
}
}