第十三课时 队列

我们都知道,在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;
		}

	}

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值