2.Java定义二叉树、二叉搜索树和Huffman树

来源:互联网 发布:手机淘宝不能付款 编辑:程序博客网 时间:2024/06/05 22:57

二叉树定义:

package com.yuan;public class BinTreeNode {private Object data;  //数据域private BinTreeNode parent;   //父结点private BinTreeNode lChild;   //左孩子private BinTreeNode rChild;   //右孩子private int height;   //以该结点为根的子树的高度private int size;   //该结点的子孙树(包括结点本身)//二叉结点的两个构造器public BinTreeNode(){this(null);}public BinTreeNode(Object e) {data=e; height=0; size=1;parent=lChild=rChild=null;}public Object getData(){return data;}public void setData(Object e){data=e;}/*****辅助方法,判断当前结点位置情况*****///判断是否有父亲public boolean hasParent(){return parent!=null;}//判断是否有左孩子public boolean hasLChild(){return lChild!=null;}//判断是否有右孩子public boolean hasRChild(){return rChild!=null;}//判断是否为叶子结点public boolean isLeaf(){return !hasLChild() && !hasRChild();}//判断是否为某结点的左孩子public boolean isLChild(){return hasParent() && this==parent.lChild;}//判断是否为某结点的右孩子public boolean isRChild(){return hasParent() && this==parent.rChild;}/*****与height相关的方法*****///获取以该结点为根的树的高度public int getHeight() { return height; }//更新当前结点及其祖先的高度public void updateHeight(){int newH=0;   //新高度初始化为0,高度等于左右子树高度加1中的大者if(hasLChild()){newH=Math.max(newH,1+getLChild().getHeight());}if(hasRChild()){newH=Math.max(newH,1+getRChild().getHeight());}if(newH==height) return;  //如果当前结点的高度没有变化,则直接返回height=newH;if(hasParent()) getParent().updateHeight();   //递归更新祖先结点的高度}/*****与size有关的方法*****///获取以当前结点为根的树的结点数public int getSize(){return size;}//更新当前结点及其祖先的子孙数public void updateSize(){size=1;   //初始化为1,结点本身if(hasLChild()) size+=getLChild().getSize();   //加上左子树的规模if(hasRChild()) size+=getRChild().getSize();   //加上右子树的规模if(hasParent()) getParent().updateSize();   //递归更新祖先的规模}/*****与parent有关的方法*****///获取当前结点的父亲结点public BinTreeNode getParent() {return parent;}//断开与父亲的关系public void server(){if(!hasParent()) return;if(isLChild()) parent.lChild=null;else  parent.rChild=null;parent.updateHeight();parent.updateSize();parent=null;}/*****与lChild有关的方法*****/public BinTreeNode getLChild() {return lChild;}//设置当前结点的左孩子,返回原来的左孩子public BinTreeNode setLChild(BinTreeNode lc){BinTreeNode oldLC = this.lChild;if(hasLChild()) lChild.server();   //如果当前结点有左孩子,则断开其左孩子和当前结点的关系if(lc!=null){lc.server();   //断开lc与其父亲结点的关系this.lChild=lc;lc.parent=this;this.updateSize();this.updateSize();}return oldLC;}/*****与rChild有关的方法*****/public BinTreeNode getRChild() {return rChild;}//设置当前结点的右孩子,返回原来的右孩子public BinTreeNode setRChild(BinTreeNode rc){BinTreeNode oldRC = this.lChild;if(hasRChild()) rChild.server();   //如果当前结点有左孩子,则断开其左孩子和当前结点的关系if(rc!=null){rc.server();   //断开lc与其父亲结点的关系this.rChild=rc;rc.parent=this;this.updateSize();this.updateSize();}return oldRC;}}

Huffman树定义:

package com.yuan;import java.util.ArrayList;import java.util.List;public class HuffmanTreeNode extends BinTreeNode { private int weight;    //当前结点的权值private String coding = "";   //编码//构造方法:构造一个哈夫曼树结点public HuffmanTreeNode(int weight){this(weight,null);}public HuffmanTreeNode(int weight, Object e) {super(e);this.weight=weight;}//改写父类的方法public HuffmanTreeNode getParent(){return (HuffmanTreeNode)super.getParent();}public HuffmanTreeNode getLChild(){return (HuffmanTreeNode)super.getLChild();}public HuffmanTreeNode getRChild(){return (HuffmanTreeNode)super.getRChild();}//get & set方法public int getWeight() {return weight;}public String getCoding() {return coding;}public void setCoding(String coding) {this.coding=coding;}/*******通过结点数组构造Huffman树*******///构造一个哈夫曼树,并返回根结点private static HuffmanTreeNode buildGuffmanTree(HuffmanTreeNode[] nodes){int n=nodes.length;if(n<2) return nodes[0];  //当数组中只有一个结点或零个元素时,返回这一个结点或空List l = new ArrayList();    //根结点线性表,按照weight从大到小有序//将结点逐一插入线性表for(int i=0;i<n;i++){insertToList(l,nodes[i]);}//选择weight最小的两棵树合并,循环n-1次for(int i=1;i<n;i++){HuffmanTreeNode min1=(HuffmanTreeNode)l.remove(l.size()-1);HuffmanTreeNode min2=(HuffmanTreeNode)l.remove(l.size()-1);HuffmanTreeNode newRoot = new HuffmanTreeNode(min1.getWeight()+min2.getWeight());newRoot.setLChild(min1);newRoot.setRChild(min2);  //合并insertToList(l,newRoot);}return (HuffmanTreeNode)l.get(0);}//将结点按照weight从大到小的顺序插入线性表private static void insertToList(List l, HuffmanTreeNode node) {for(int j=0;j<l.size();j++){if(node.getWeight()>((HuffmanTreeNode)l.get(j)).getWeight()){l.add(j, node);return;}}l.add(l.size(), node);}//从根结点开始,递归生成Huffman编码private static void generateHuffamnCode(HuffmanTreeNode root){if(root==null) return;if(root.hasParent()){if(root.isLChild())root.setCoding(root.getParent().getCoding()+"0");   //向左为0elseroot.setCoding(root.getParent().getCoding()+"1");   //向右为1}generateHuffamnCode(root.getLChild());generateHuffamnCode(root.getRChild());}}

二叉搜索树:

package com.yuan;public class BinarySearchTree<AnyType extends Comparable<? super AnyType>>{//定义内部类,二叉树节点的结构private static class BinaryNode<AnyType>{AnyType element;BinaryNode<AnyType> left;BinaryNode<AnyType> right;//构造器BinaryNode(AnyType theElement){this(theElement,null,null);}BinaryNode(AnyType theElement, BinaryNode<AnyType> lt, BinaryNode<AnyType> rt) {element=theElement;left=lt;right=rt;}}//定义二叉搜索树的成员变量——根结点private BinaryNode<AnyType> root;   //定义根结点//二叉搜索树的构造器——创建一个空的二叉树public BinarySearchTree(){root=null;}/********二叉搜索树的方法********///清空二叉搜索树:将根结点置空即可public void makeEmpty(){root=null;}//判断二叉搜索树是否为空public boolean isEmpty(){return root==null;}//判断以root为根结点的二叉搜索树是否包含值为x的结点public boolean contains(AnyType x){return contains(x, root);}private boolean contains(AnyType x, BinaryNode<AnyType> t) {if(t==null) return false;int compareResult = x.compareTo(t.element);if(compareResult<0)return contains(x,t.left);else if(compareResult>0)return contains(x,t.right);elsereturn true;}//寻找以root为根结点的二叉搜索树的最小值(递归实现)public AnyType findMin() throws Exception{if(isEmpty())throw new Exception();return findMin(root).element;}private BinaryNode<AnyType> findMin(BinaryNode<AnyType> t) {if(t==null) return null;else if(t.left==null) return t;return findMin(t.left);}//寻找以root为根结点的二叉搜索树的最大值(非递归实现)public AnyType findMax() throws Exception{if(isEmpty())throw new Exception();return findMax(root).element;}private BinaryNode<AnyType> findMax(BinaryNode<AnyType> t) {if(t==null) return null;else{while(t.right!=null)t=t.right;return t;}}//向二叉搜索树中插入元素x(一定是插入到树的叶子结点上,所以判断条件是是否等于null),并返回插入后的二叉搜索树的根结点public void insert(AnyType x){root=insert(x,root);}private BinaryNode<AnyType> insert(AnyType x, BinaryNode<AnyType> t) {if(t==null)return new BinaryNode(x, null,null);int compareResult = x.compareTo(t.element);if(compareResult<0)t.left = insert(x,t.left);if(compareResult>0)t.right = insert(x,t.right);else; //树中已存在该元素,do nothingreturn t;}//移除以root为根结点的二叉搜索树中元素为x的结点public void remove(AnyType x){root=remove(x,root);}private BinaryNode<AnyType> remove(AnyType x, BinaryNode<AnyType> t) {if(t==null)return t;int compareResult = x.compareTo(t.element);if(compareResult<0)t.left = remove(x,t.left);else if(compareResult>0)t.right = remove(x,t.right);//如果x刚好是结点t的元素值,则删除结点telse if(t.left!=null && t.right!=null)  //有两个孩子{t.element=findMin(t.right).element;   //用右子树的最小值代替原来的tt.right=remove(t.element, t.right);  //用删除最小结点后的右子树作为新结点t的右孩子}else{t=(t.left!=null)?t.left:t.right;   //有一个孩子}return t;}}


原创粉丝点击