接口
/*1.开发时间:2014-11-5 *2.开发者:赵远 *3.维护者:赵远 *3.程序说明:树的接口 *4.注意事项:暂且没有 * **/ package Tree; import Tree.node; public interface TreeNode { // class Node {}; // 1. 求二叉树中的节点个数 int GetNodeNum(node root); // 2. 求二叉树的深度 int GetDepth(node root); // 3. 前序遍历,中序遍历,后序遍历 void PreOrderTraverse(node root); void InOrderTraverse(node root); void PostOrderTraverse(node root); // 4.分层遍历二叉树(按层次从上往下,从左往右) void LevelTraverse(node root); // 5. 将二叉查找树变为有序的双向链表 // 6. 求二叉树第K层的节点个数 // 7. 求二叉树中叶子节点的个数 // 8. 判断两棵二叉树是否结构相同 // 9. 判断二叉树是不是平衡二叉树 // 10. 求二叉树的镜像 // 11. 求二叉树中两个节点的最低公共祖先节点 // 12. 求二叉树中节点的最大距离 // 13. 由前序遍历序列和中序遍历序列重建二叉树 // 14.判断二叉树是不是完全二叉树 }
节点
package Tree; //* 结点类。 public class node { public Object data; // 该节点存储的值。 public node leftChild; // 指向左子节点的引用。 public node rightChild; // 指向右子节点的引用。 public node(Object value) { this.data = value; leftChild = null; rightChild = null; } }
具体实现
/*1.开发时间:2014-11-13 *2.开发者:赵远 *3.维护者:赵远 *3.程序说明:二叉树的方法實現 *4.注意事项:暂且没有 * **/ package Tree; import Tree.node; import Tree.ArrayQueue; public class BinaryTreeNode implements TreeNode { private node root; // 根节点 BinaryTreeNode() { root = null; } // 1. 求二叉树中的节点个数 // 递归解法: // (1)如果二叉树为空,节点个数为0 // (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1 public int GetNodeNum(node root) { if (root == null) // 递归出口 return 0; return GetNodeNum(root.rightChild) + GetNodeNum(root.leftChild) + 1; }; // 2. 求二叉树的深度 // 递归解法: // (1)如果二叉树为空,二叉树的深度为0 // (2)如果二叉树不为空,二叉树的深度 = max(左子树深度, 右子树深度) + 1 public int GetDepth(node root) { if (root == null) // 递归出口 return 0; int depthLeft = GetDepth(root.leftChild); int depthRight = GetDepth(root.rightChild); return depthLeft > depthRight ? (depthLeft + 1) : (depthRight + 1); }; // 3. 前序遍历,中序遍历,后序遍历 // 前序遍历递归解法: // (1)如果二叉树为空,空操作 // (2)如果二叉树不为空,访问根节点,前序遍历左子树,前序遍历右子树 // private void Visit(Node root){函数独立 // if (root == null) // return ; // System.out.print("......"); // Visit(root.leftChild); // 前序遍历左子树 // Visit(root.rightChild); // 前序遍历右子树 // }; public void PreOrderTraverse(node root) { if (root == null) return; System.out.print(root.data + " "); PreOrderTraverse(root.leftChild); PreOrderTraverse(root.rightChild); // Visit(root); 函数独立 }; // 中序遍历递归解法 // (1)如果二叉树为空,空操作。 // (2)如果二叉树不为空,中序遍历左子树,访问根节点,中序遍历右子树 public void InOrderTraverse(node root) { if (root == null) return; InOrderTraverse(root.leftChild); System.out.print(root.data + " "); InOrderTraverse(root.rightChild); // }; // 后序遍历递归解法 // (1)如果二叉树为空,空操作 // (2)如果二叉树不为空,后序遍历左子树,后序遍历右子树,访问根节点 public void PostOrderTraverse(node root) { PostOrderTraverse(root.leftChild); PostOrderTraverse(root.rightChild); System.out.print(root.data + " "); }; // 4.分层遍历二叉树(按层次从上往下,从左往右) // 队列初始化,将根节点压入队列。 // 当队列不为空,进行如下操作:弹出一个节点,访问,若左子节点或右子节 // 点不为空,将其压入队列。 public void LevelTraverse(node root) { ArrayQueue q = new ArrayQueue(); if (root == null) return; q.enQueue(root); while (!q.isEmpty()) { root.data = q.getFront(); q.deQueue(); System.out.print(root.data + " "); // 访问节点 if (root.leftChild != null) q.enQueue(root.leftChild); if (root.rightChild != null) q.enQueue(root.rightChild); } return; } // 5. 求二叉树第K层的节点个数 // 递归解法: // (1)如果二叉树为空或者k<1返回0 // (2)如果二叉树不为空并且k==1,返回1 // (3)如果二叉树不为空且k>1,返回左子树中k-1层的节点个数与右子树k-1层节点个数之和 int GetNodeNumKthLevel(node root, int k) { if(root == null || k < 1) return 0; if(k == 1) return 1; int numLeft = GetNodeNumKthLevel(root.leftChild, k-1); // 左子树中k-1层的节点个数 int numRight = GetNodeNumKthLevel(root.rightChild, k-1); // 右子树中k-1层的节点个数 return (numLeft + numRight); } // 6. 求二叉树中叶子节点的个数 // 递归解法: // (1)如果二叉树为空,返回0 // (2)如果二叉树不为空且左右子树为空,返回1 // (3)如果二叉树不为空,且左右子树不同时为空,返回左子树中叶子节点个数加上右子树中叶子节点个数 int GetLeafNodeNum(node root) { if(root == null) return 0; if(root.leftChild == null && root.rightChild == null) return 1; int numLeft = GetLeafNodeNum(root.leftChild); // 左子树中叶节点的个数 int numRight = GetLeafNodeNum(root.leftChild); // 右子树中叶节点的个数 return (numLeft + numRight); } // 7. 判断两棵二叉树是否结构相同 // 不考虑数据内容。结构相同意味着对应的左子树和对应的右子树都结构相同。 // 递归解法: // (1)如果两棵二叉树都为空,返回真 // (2)如果两棵二叉树一棵为空,另一棵不为空,返回假 // (3)如果两棵二叉树都不为空,如果对应的左子树和右子树都同构返回真,其他返回假 boolean StructureCmp(node root1, node root2) { if(root1 == null && root2 == null) // 都为空,返回真 return true; else if(root1 == null || root2 == null) // 有一个为空,一个不为空,返回假 return false; boolean resultLeft = StructureCmp(root1.leftChild,root2.leftChild); // 比较对应左子树 boolean resultRight = StructureCmp(root1.rightChild, root2.rightChild); // 比较对应右子树 return (resultLeft && resultRight); } // 8. 判断二叉树是不是平衡二叉树 // 递归解法: // (1)如果二叉树为空,返回真 // (2)如果二叉树不为空,如果左子树和右子树都是AVL树并且左子树和右子树高度相差不大于1,返回真,其他返回假 boolean IsAVL(node root, int height) { if(root == null) // 空树,返回真 { height = 0; return true; } int heightLeft = 0; boolean resultLeft = IsAVL(root.leftChild, heightLeft); int heightRight = 0; boolean resultRight = IsAVL(root.rightChild, heightRight); if(resultLeft && resultRight && abs(heightLeft - heightRight) <= 1) // 左子树和右子树都是AVL,并且高度相差不大于1,返回真 { height = max(heightLeft, heightRight) + 1; return true; } else { height = max(heightLeft, heightRight) + 1; return false; } } private int max(int heightLeft, int heightRight) { return heightLeft>heightRight?heightLeft:heightRight; } private int abs(int i) { if(i>0) return i; else return -i; } //9.递归方法插入节点 public node insert(node root, Object x) { node p = null ; p.data=x; p.leftChild=null; p.rightChild=null; if(root == null){ root = p; } else if(root.leftChild== null){ root.leftChild = insert(root.leftChild,x); } else if(root.rightChild== null){ root.rightChild= insert(root.rightChild,x); } return root; } }
引用一个队列
package Tree; /** * * @author 上课 */ public class ArrayQueue implements Queue { private Object[] data; private int front; private int rear; public ArrayQueue(int capacity) { this.data = new Object[capacity]; this.front = this.rear = 0; } public ArrayQueue() { this(1024); } public void clear() { this.front = this.rear = 0; } public boolean isEmpty() { return this.front == this.rear; } public Object getFront() { if (isEmpty()) { throw new UnsupportedOperationException("队列已空"); } return data[front]; } public void enQueue(Object o) { if (isFull()) { throw new UnsupportedOperationException("队列已满"); } this.data[rear++] = o; rear %= data.length; } public Object deQueue() { throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates. } private boolean isFull() { return ((rear + 1) % data.length) == front; } }
时间: 2024-10-27 17:03:50