實現二叉樹的常用操作算法:
包括二叉樹的建立、遍歷、求高度、線索化等操作
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();
}
}