我们都知道,在java中有个很方便的储存一个集合的东西叫数组,它允许我们存取同一类型的数,而且使用起来简单方便,但是,既然有优点,那肯定会有缺点。缺点就是数组无法改变其大小,你定义多大就多大,无法在改变(除非你重新new一个出来)
而队列就弥补了这种缺点,队列的大小并不是一开始就固定的,而是随着你加入的数的多少而改变。所以队列更能节省内存资源。
学过c语言或者c++的同学可能会想,队列和链表有什么区别?
我觉得吧,链表是我们直接控制指针其实本质上队列也是在控制指针,但在java中不允许操控指正,所以更安全。
链表
上次说到队列与链表的区别,这里我再补充一下。队列在计算机中是一段连续的存储空间,而链表却并不是,链表由一个个节点构成,在内存中不连续,就好像是几个零散的珠子用线把他们连起来一样。
举个更形象的比喻,链表就好像做任务,从一个npc到另一个npc,一个一个的连起来。
我们有了队列,为什么还需要链表呢?其实对于c++来说本无多大区别,因为c++的内存是要认为去释放的,由于这种原因,不要的内存可以马上释放掉,而java不同,他的内存是由gc释放的,而gc不是认为控制的,所以内存可能不会及时释放(这算是个优点也算缺点吧,对于马虎的程序员来说也许更适合学java)。队列就是那种不会及时释放的。因为他本质来时使用数组。而链表则是要多少拿多少的形式。
实例:哈夫曼树构建与实现简单转码
package cn.czm0801; import java.util.List; import java.util.PriorityQueue; public class HuffmanTree { private Node root;//根节点 private PriorityQueue<Node> pq;//优先队列 public HuffmanTree(PriorityQueue<Node> pq){ this.pq = pq; } /** * 添加节点方法 * @param n1 * @param n2 */ public void add(Node n1,Node n2){ Node n = new Node((char)(0),n1.getCount()+n2.getCount()); n.setLeft(n1); n.setRight(n2); pq.add(n); } /** * 创建哈夫曼树方法 */ public void createTree(){ while(pq.size()>1){ this.add(pq.poll(), pq.poll()); } root = pq.peek(); } public void ergodic(Node current,String str){ if(current.getLeft()==null && current.getRight()==null){ current.setCode(str); System.out.println(current + " 编码是 " + current.getCode()); return; } this.ergodic(current.getLeft(), str + "0"); this.ergodic(current.getRight(), str + "1"); } /** * 还原内容 * @param str * @param list */ public void restore(String strCode,List<Node> list,final int length){ String str = ""; int count = 0; int i =0; while(count <length){ if(strCode.indexOf(list.get(i%list.size()).getCode())==0){ count ++; strCode = strCode.substring(list.get(i%list.size()).getCode().length()); str = str +list.get(i%list.size()).getCh(); } i++; } System.out.println("恢复后的内容是 "+str); } public Node getRoot() { return root; } }
package cn.czm0801; public class Node { private char ch;//字符 private int count;//次数 private String code;//编码 // 左子树节点 private Node left; // 右子树节点 private Node right; public Node(char ch, int count) { this.ch = ch; this.count = count; } public char getCh() { return ch; } public void setCh(char ch) { this.ch = ch; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } 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; } public String toString(){ return ch + " 出现次数是" + count; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } }
package cn.czm0801; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.PriorityQueue; public class Test { /** * @param args */ public static void main(String[] args) { String str = "fdjhjfhvcvnlhvnbcvur"; List<Node> list = new ArrayList<Node>(); statistic(str,list); /** * 使用匿名类,创建比较器 */ Comparator<Node> comparator = new Comparator<Node>(){ public int compare(Node n1, Node n2) { if(n1.getCount() > n2.getCount()){ return 1; }else if(n1.getCount()< n2.getCount()){ return -1; }else{ if(n1.getCh() > n2.getCh()){ return 1; }else if(n1.getCh() < n2.getCh()){ return -1; }else{ return 0; } } } }; //优先队列 PriorityQueue<Node> pq = new PriorityQueue<Node>(list.size(),comparator); for(int i = 0;i<list.size();i++){ pq.add(list.get(i)); } //构建哈夫曼树 HuffmanTree ht = new HuffmanTree(pq); ht.createTree(); ht.ergodic(ht.getRoot(), ""); //把字符串转换成编码格式 char[] ch = str.toCharArray(); String strCode =""; for(int i = 0;i<ch.length;i++){ for(int j = 0;j<list.size();j++){ if(ch[i]==list.get(j).getCh()){ strCode = strCode + list.get(j).getCode(); break; } } } System.out.println("转码后的内容是 " + strCode); ht.restore(strCode, list, str.length());//恢复内容 } /** * 统计字符出现的次数 * @param str * @param list */ public static void statistic(String str,List<Node> list){ char[] ch = str.toCharArray(); boolean isAppear = false; for(int i =0 ;i<ch.length;i++){ for(int j = 0; j < list.size();j++){ if(list.get(j).getCh() == ch[i]){ list.get(j).setCount(list.get(j).getCount()+1); isAppear = true; break; } } if(!isAppear){ list.add(new Node(ch[i],1)); } isAppear = false; } } }
相关推荐
在本节三年级数学下册第三单元的乘法教学中,主要关注的是乘法运算的技巧和规律,特别是针对两位数乘以两位数的计算。这节课的主题是“队列表演(一)”,通过实际场景帮助学生理解并掌握乘法运算。 1. 计算 13×12...
在本节三年级数学下册第三单元的乘法课程中,主要关注的是乘法运算,特别是与数字11相乘的规律。这个知识点是基础数学中的一个重要部分,它可以帮助学生掌握快速计算技巧,提高运算速度。 首先,我们来看第一个练习...
第十一至十三课时:UCOS扩展功能 这部分将介绍UCOS的高级特性,比如定时器服务、动态加载任务、动态内存池扩展等。通过这些扩展,你可以根据项目需求定制和优化UCOS。 第十四课时:实战项目 在本课时中,你将利用...
《第3单元 乘法》是小学三年级数学下册中的重要内容,主要针对北师大版教材设计的教学单元。本单元的教学目标旨在通过具体情境,帮助学生理解和掌握两位数乘以整十数以及两位数乘以两位数的计算方法,同时培养学生的...
10. 工作负载管理和资源调度,包括创建和分配资源队列 11. 数据的装载和卸载 这个Java课程大纲旨在提供一个全面的学习路径,从基础的Java语法和数据库操作,到大数据处理的前沿技术,为学生提供了扎实的理论基础和...
7. 音乐游戏:第二课时中的音乐游戏“队列操”旨在提高学生的音乐感知和团队协作能力,同时享受表演的乐趣。 8. 音乐欣赏:通过观看录像和听录音,学生可以加深对革命历史歌曲的理解,以及对少先队和共产儿童团的...
三、教材分析: 走和跑的练习中,主要发展学生的速度、耐力为主要的练习内容,全面提高学生的身体素质,主要的内容以快速跑、耐久跑等为主,其次、以蹲距式跳远、上步垒球掷远及基本体操知识为主,并加大迎面接力跑...
* 调用第三方库函数 * lambda函数 6. Python语言基础字符串处理 * 字符串的索引 * 字符串的切片 * 字符串的其他常用操作 7. 系统思维冯诺依曼结构 * 简单应用冯诺依曼结构 * 进阶应用冯诺依曼结构 8. 算法...
#### 13. 算法竞赛入门经典(第2版)》(推荐指数:5颗星) - **出版信息**:此书出版于2014年6月,作者刘汝佳。 - **核心知识点**: - 算法基础:全面覆盖算法基础知识。 - 数据结构:详细介绍常见数据结构。 - ...