1、统计学生学分
学生考试结果 A B C D
学分增加 5 4 3 0
人数 10 50 30 10
代码1:
if A : +5
else if B : +4
else if C : +3
else D :0
这份代码执行的效率为:10 + 50*2 +30*3 +10*3
代码2:
if B :+4
else if C:+3
else if A: +5
else D : 0
这份代码执行的效率为: 50 + 30 *2 +(10+10)*3
显然代码二比代码一的效率要高
在计算机数据处理中,霍夫曼编码使用变长编码表对源符号(如文件中的一个字母)进行编码,其中变长编码表是通过一种评估来源符号出现机率的方法得到的,出现机率高的字母使用较短的编码,反之出现机率低的则使用较长的编码,这便使编码之后的字符串的平均长度、期望值降低,从而达到无损压缩数据的目的。
2.哈夫曼二叉树
* 权值:出现次数
* 路径:当前节点到根节点的层数
* 加权路径:权值*路径
*
* 哈夫曼二叉树:所有节点加权路径和最小的二叉树
*
根据字符串构建哈夫曼二叉树
*
* 第一步:统计字符串中各个字母出现次数,并且生成节点
* 第二步:根据节点的权值排序
* 第三步:取出权限最小的两个节点,构建一个新节点
* 第四步:重复2 3,直到只剩一个节点,该节点就是根节点。
代码部分:
1.节点类
public class Node {
private Object data;//数据
private Node left;//左节点
private Node right;//右节点
private int weight;//权值
public Node(){
}
public Node(Object data,int weight){
super();
this.data = data;
this.weight = weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public Node getLeft() {
return left;
}
public void setLeft(Node left) {
this.left = left;
}
public Node getRight() {
return right;
}
public void setRight(Node right) {
this.right = right;
}
}
2.哈夫曼二叉树类
public class HalfmenTree<E> {
private Node root;
private int[] num = new int[128];// 权值数组
// 声明一个队列存字符的Ascll码对象
ArrayList<Object> numlist = new ArrayList<Object>();
// 声明一个队列存贮节点
ArrayList<Node> list = new ArrayList<Node>();
// 根据字母的权值排序从小到大(冒泡排序)
public void paixu(){
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
if (list.get(i).getWeight() > list.get(j).getWeight()) {
Node node = list.get(i);
list.set(i, list.get(j));
list.set(j, node);
}
}
}
}
public void add(String str) {
// 将str拆成单个字符,并根据其对应的Ascll码存放在num权值数组中
for (int i = 0; i < str.length(); i++) {
char ch = str.charAt(i);
int n = (int) ch;
num[n]++;
if (num[n] == 1) {// 当每个字母第一次出现时,将这个字母的Ascll码存进numlist
numlist.add(n);
}
}
// 生成节点
for (int i = 0; i < numlist.size(); i++) {
int n = (int) numlist.get(i);
int m = num[n];
char ch = (char) n;
Node node = new Node(ch, m);
list.add(node);
}
// 根据字母的权值排序从小到大(冒泡排序)
paixu();
// 排序后输出节点的字母和权值
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i).getData() + " " + list.get(i).getWeight());
}
System.out.println("=======================");
// 取出权值最小的两个节点,构建一个新节点
while (list.size() > 1) {
Node left = list.remove(0);
Node right = list.remove(0);
String st = left.getData().toString() + right.getData().toString();//st为左右子节点的字母并在一起
Node father = new Node(st, left.getWeight() + right.getWeight());
father.setLeft(left);
father.setRight(right);
list.add(0, father);
paixu();//排序
}
// 让根节点等于最后一个节点
root = list.get(0);
}
/**
* 递归遍历
*/
public void output() {
output(root);
}
public void output(Node node) {
//后序遍历
if (node.getLeft() != null) {
output(node.getLeft());
if (node.getRight() != null) {
output(node.getRight());
}
}
System.out.println(node.getData() + " " + node.getWeight());
}
}
3.测试类
public class Manage2 {
public static void main(String[] args) {
HalfmenTree ht = new HalfmenTree();
ht.add("sadadsadaaqweqeadad");
ht.output();
}
}
运行结果为: