char[] chars = str.toCharArray();
List<CodeNode> nodeList = getCodeNodes(chars);
Collections.sort(nodeList);//将链表表按照升序进行排列
// System.out.println(nodeList);
//测试创建的哈夫曼树
CodeNode root = creatTree(nodeList);
// root.preOrder();
toCode(root,"",stringBuilder);
System.out.println(map);
}
//统计字符数组中字符出现的个数,存入哈市表中,并转换链表返回
public static List<CodeNode> getCodeNodes(char[] chars){
//1.创建一个Arrayslist
ArrayList<CodeNode> list = new ArrayList<>();
//2.存储每个字符出现的次数,遍历字符数组,并将其存放到hash表中
Hashtable<Character, Integer> hashtable = new Hashtable<>();
for (char ch:chars) {
Integer conuts = hashtable.get(ch);//统计ch在hashTable中出现的次数
if(conuts == null){//如果ch在hashTable中出现的次数为空,则将ch存入hashTable中,并将次数置为1
hashtable.put(ch,1);
}else {
hashtable.put(ch,conuts+1);//如果已经存在就将其的value值加一
}
}
//循环结束,对hash表进行遍历,创建节点,存到ArraysList链表中,开始构造树节点
for (Map.Entry<Character, Integer> node: hashtable.entrySet()) {
list.add(new CodeNode(node.getKey(),node.getValue()));
}
return list;
}
//创建哈夫曼树
public static CodeNode creatTree(List<CodeNode> list){
while (list.size() > 1){
Collections.sort(list);
CodeNode leftNode = list.get(0);
CodeNode rightNode = list.get(1);
int leftCount = leftNode.count;
int righrCount = rightNode.count;
CodeNode parent = new CodeNode((leftCount+righrCount));
parent.left = leftNode;
parent.right = rightNode;
list.remove(leftNode);
list.remove(rightNode);
list.add(parent);
}
return list.get(0);
}
//前序遍历
public static void preOrder(CodeNode root){
if (root != null){
root.preOrder();
}else{
System.out.println("此树为空");
}
}
//创建一个map将哈夫曼编码存放在Map<char,String>
static Map<Character,String> map = new HashMap();
//在生成哈夫曼编码时,需要拼接路径,定义一个StringBUilder存储有叶子节点的路径
static StringBuilder stringBuilder = new StringBuilder();
//将哈夫曼树转换成哈夫曼编码
public static void toCode(CodeNode node,String code,StringBuilder stringBuilder){
StringBuilder stringBuilder1 = new StringBuilder(stringBuilder);
//将code添加到stringBuilder1中。
stringBuilder1.append(code);
if(node.left == null || node.right == null){
map.put(node.c,stringBuilder1.toString());
}else {//说明已经到达叶子节点,返回结果
//向左递归
toCode(node.left,"0",stringBuilder1);
//向右递归
toCode(node.right,"1",stringBuilder1);
}
}
}
/**
-
c : 存放字符本身
-
count : 字符本身出现的次数,及权值
*/
class CodeNode implements Comparable{
char c;
int count;
Spring全套教学资料
Spring是Java程序员的《葵花宝典》,其中提供的各种大招,能简化我们的开发,大大提升开发效率!目前99%的公司使用了Spring,大家可以去各大招聘网站看一下,Spring算是必备技能,所以一定要掌握。
目录:
部分内容:
Spring源码
- 第一部分 Spring 概述
- 第二部分 核心思想
- 第三部分 手写实现 IoC 和 AOP(自定义Spring框架)
- 第四部分 Spring IOC 高级应用
基础特性
高级特性 - 第五部分 Spring IOC源码深度剖析
设计优雅
设计模式
注意:原则、方法和技巧 - 第六部分 Spring AOP 应用
声明事务控制 - 第七部分 Spring AOP源码深度剖析
必要的笔记、必要的图、通俗易懂的语言化解知识难点
脚手框架:SpringBoot技术
它的目标是简化Spring应用和服务的创建、开发与部署,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用的微服务功能,可以和spring cloud联合部署。
Spring Boot的核心思想是约定大于配置,应用只需要很少的配置即可,简化了应用开发模式。
- SpringBoot入门
- 配置文件
- 日志
- Web开发
- Docker
- SpringBoot与数据访问
- 启动配置原理
- 自定义starter
微服务架构:Spring Cloud Alibaba
同 Spring Cloud 一样,Spring Cloud Alibaba 也是一套微服务解决方案,包含开发分布式应用微服务的必需组件,方便开发者通过 Spring Cloud 编程模型轻松使用这些组件来开发分布式应用服务。
- 微服务架构介绍
- Spring Cloud Alibaba介绍
- 微服务环境搭建
- 服务治理
- 服务容错
- 服务网关
- 链路追踪
- ZipKin集成及数据持久化
- 消息驱动
- 短信服务
- Nacos Confifig—服务配置
- Seata—分布式事务
- Dubbo—rpc通信
Spring MVC
目录:
部分内容:
Spring MVC
目录:
[外链图片转存中…(img-i2lIjvdE-1714346426796)]
[外链图片转存中…(img-wM02kCXQ-1714346426796)]
[外链图片转存中…(img-tdlzAt8T-1714346426797)]
部分内容:
[外链图片转存中…(img-PBqQBGfj-1714346426797)]
[外链图片转存中…(img-ECVYG771-1714346426797)]