二叉树

来源:互联网 发布:屏蔽淘宝网 百度 编辑:程序博客网 时间:2024/06/03 18:49

package binarytree;import java.util.ArrayDeque;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Queue;public class Tree2<T> {private TreeNode root;public Tree2(T data) {root = new TreeNode(data);}// 输入数组,初始化树public Tree2(Object[] str, String singal) {if (str.length == 0) {throw new RuntimeException("初始化数组为空!");}this.root = new TreeNode(str[0]);initTree(str, singal);}/*** * 根据传入的数组初始化二叉树 * 数组按层级遍历传入,按照层级遍历思想将其初始化 * @param list传入的数组 * @param singal  空节点标记 */private void initTree(Object[] list, String singal) {Queue<TreeNode> queue = new ArrayDeque<>();queue.add(root);//将根节点加入for (int i = 1; i < list.length; i++) {TreeNode node = queue.poll(); // 取出队列元素TreeNode leftNode = new TreeNode(list[i]); // 创建左节点if (leftNode.data != singal) {node.left = leftNode;queue.add(leftNode); // 加入左节点}if (++i < list.length) {TreeNode rightNode = new TreeNode(list[i]); // 创建右节点if (leftNode.data != singal) {node.right = rightNode;queue.add(rightNode); // 加入右节点}}}}// 判断树是否为空public boolean isEmpty() {if (root == null)return true;elsereturn false;}// 获得根节点public TreeNode getRoot() {if (isEmpty())throw new RuntimeException("根节点为空!!!");return root;}// 获得树的深度public int deep() {return deep(root);}private int deep(TreeNode node) {if (node == null)return 0;else if (node.left == null && node.right == null)return 1;else {int leftDeep = deep(node.left);int rightDeep = deep(node.right);int max = leftDeep > rightDeep ? leftDeep : rightDeep;//取最大子节点的深度return ++max;//加上本节点}}// 添加一个节点public TreeNode addNode(TreeNode parent, T data, boolean isLeft) {if (parent == null)throw new RuntimeException("父节点为空,添加失败!");else if (isLeft && parent.left != null)throw new RuntimeException("左节点已存在,添加失败!");else if (!isLeft && parent.right != null)throw new RuntimeException("右节点已存在,添加失败!");else {TreeNode node = new TreeNode(data);if (isLeft)parent.left = node;elseparent.right = node;return node;}}/*** * 层级遍历二叉树 * 讲述的节点放到队列中,然后取出队列的头结点,访问其的子节点,如果子节点存在即放入队列中,输出当前节点 * @return */public List<TreeNode> levelTraverse() {Queue<TreeNode> queue = new ArrayDeque<>();List<TreeNode> list = new ArrayList<>();if (root == null)throw new RuntimeException("根节点不存在,遍历失败!");queue.offer(root);while (!queue.isEmpty()) {TreeNode node = queue.peek();list.add(node);queue.poll(); // 将队列的头结点取出if (node.left != null)queue.offer(node.left); // 将当前节点的左节点加入队列中if (node.right != null)queue.offer(node.right);}return list;}// 先序遍历public List<TreeNode> preTraverse() {if (root == null) {throw new RuntimeException("根节点不存在");}return preOrderTraverse(root);}private List<TreeNode> preOrderTraverse(TreeNode node) {List<TreeNode> list = new ArrayList<>();list.add(node);if (node.left != null) {list.addAll(preOrderTraverse(node.left));}if (node.right != null) {list.addAll(preOrderTraverse(node.right));}return list;}// 中序遍历public List<TreeNode> inTraverse() {if (root == null) {throw new RuntimeException("根节点不存在");}return inOrderTraverse(root);}private List<TreeNode> inOrderTraverse(TreeNode node) {List<TreeNode> list = new ArrayList<>();if (node.left != null) {list.addAll(preOrderTraverse(node.left));}list.add(node);if (node.right != null) {list.addAll(preOrderTraverse(node.right));}return list;}// 后序遍历public List<TreeNode> postTraverse() {if (root == null) {throw new RuntimeException("根节点不存在");}return postOrderTraverse(root);}private List<TreeNode> postOrderTraverse(TreeNode node) {List<TreeNode> list = new ArrayList<>();if (node.left != null) {list.addAll(preOrderTraverse(node.left));}if (node.right != null) {list.addAll(preOrderTraverse(node.right));}list.add(node);return list;}public TreeNode getCommonParent(T a,T b){int index=getCommonParentIndex(a, b);TreeNode node=getTreeNodeByIndex(index);return node;}/*** * 根据两个子节点的值获取到第一个共同父节点的下标 * @param a  * @param b * @return 父节点下标值 */private int getCommonParentIndex(T a,T b){int n,m;//n,m分别任a,b节点的下标n=m=0;int parent=1;//当前节点的下标TreeNode node=null;//创建map,值(节点,节点下标)Map<TreeNode,Integer>map=new HashMap<>();//队列的值为mapQueue<Map<TreeNode,Integer>>queue=new ArrayDeque<>();Map<TreeNode,Integer> mapRoot=new HashMap<>();mapRoot.put(root, 1);//将根节点加入到map中queue.add(mapRoot);while(!queue.isEmpty()){map=queue.poll();for (TreeNode key : map.keySet()) {node=key;}//检测该节点是否为a节点if(node.data.equals(a)){n=map.get(node);}//检测该节点是否为b节点else if(node.data.equals(b)){m=map.get(node);}//当两个节点都找到后,直接提跳出if(m>0&&n>0){break;}//如果该节点的左节点不为空,将其加入到队列中if(node.left!=null){Map<TreeNode,Integer> mp=new HashMap<>();mp.put(node.left, map.get(node)*2);//左节点的下标为父节点的2倍queue.add(mp);}if(node.right!=null){Map<TreeNode,Integer> mp=new HashMap<>();mp.put(node.right, map.get(node)*2+1);  //右节点的下标为父节点的2倍加1queue.add(mp);}}System.out.println(a+"下标:"+n+"   "+b+"下标:"+m);//将m、n不断选出大的数并将其除2,直到m=n,其中将n设置为大的那个int temp;while(m!=n){if(n<m){temp=n;n=m;m=temp;}n=n/2;}return n;}/*** * 根据下标获得节点 * @param index * @return */public TreeNode getTreeNodeByIndex(int index){Map<TreeNode,Integer> map=new HashMap<>();//存放节点及下标Queue<Map<TreeNode,Integer>>queue=new ArrayDeque<>();TreeNode cnode=null;//当前nodeMap<TreeNode,Integer> cMap;//当前mapmap.put(root, 1);queue.add(map);//将根节点压入队列while(!queue.isEmpty()){cMap=queue.poll();for(TreeNode node:cMap.keySet()){cnode=node;}if(cMap.get(cnode)==index){return cnode;}}return null;}// 静态内部类public static class TreeNode {public Object data;public TreeNode left;public TreeNode right;public TreeNode(Object data) {this.data = data;}}public static void main(String[] args) {Tree2<String> tree = new Tree2<>("root");tree.addNode(tree.root, "b", true);tree.addNode(tree.root, "c", false);System.out.println(tree.deep());System.out.println("层级遍历");List<TreeNode> list = tree.levelTraverse();for (TreeNode treeNode : list) {System.out.print(treeNode.data + " ");}System.out.println();System.out.println("先序遍历");List<TreeNode> preList = tree.preTraverse();for (TreeNode treeNode : preList) {System.out.print(treeNode.data + " ");}System.out.println();System.out.println("中序遍历");List<TreeNode> inList = tree.inTraverse();for (TreeNode treeNode : inList) {System.out.print(treeNode.data + " ");}System.out.println();System.out.println("后序遍历");List<TreeNode> postList = tree.postTraverse();for (TreeNode treeNode : postList) {System.out.print(treeNode.data + " ");}System.out.println();String[] str = { "a", "b", "c", "*", "*", "d", "e", "f" };Tree2<String> t = new Tree2<>(str, "*");System.out.println("先序遍历");List<TreeNode> pList = t.preTraverse();for (TreeNode treeNode : pList) {System.out.print(treeNode.data + " ");}System.out.println();TreeNode parentNode=t.getCommonParent("a", "c");System.out.println("父节点为:"+parentNode.data);}}

二叉树,二叉树,二叉树,我要爬上你的树顶,将你降服

0 0
原创粉丝点击