- 浏览: 696755 次
- 性别:
- 来自: 杭州
文章分类
最新评论
java库里的PriorityQueue无法满足我,它不能固定容量,不遍历(遍历后就无序了),它的排序因字是从小到大(虽然可以用Comparator来反转大小顺序)。我所要的是可以固定容量(在一大堆数据通信中选择最大或最小的几个数时很有用),可遍历(不是一个个poll())。
于是,在有空的时间里写了一下。内容是一个双向链表(带头的,头不作保存数据),用插入排序。个人认为一个个添加的用插入排序效果比较好。从队尾到队头找合适的插入位置,是稳定的排序。
添加的实体可以用Comparator或Comparable,如果这两个都不是,就失去排序的效果。实现了比较高兴,发表下。
package net.blogjava.chenlb.util;
import java.util.AbstractQueue;
import java.util.Comparator;
import java.util.Iterator;
/**
* @param <E>
* 容量capacity大于0,最多只能添加capacity个,多出的被删除掉.<br/>
* 删除时根据{@link Comparable}或{@link Comparator} 和 desc
* 如果comparator==null时使用Comparable<br/>
* non-thread safe
* @author chenlb 2008-4-23 下午11:31:06
*/
public class TopPriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int size;
private LinkedItem head;
private LinkedItem last;
private int top; //top>0后,容量有限制
private Comparator<? super E> comparator;
private boolean desc; //降序
/**
* 容量无限制,升序.
*/
public TopPriorityQueue() {
this(0, null, false);
}
/**
* 容量无限制,
* @param desc true为降序.
*/
public TopPriorityQueue(boolean desc) {
this(0, null, desc);
}
/**
* 容量无限制,升序,用comparator排序
*/
public TopPriorityQueue(Comparator<? super E> comparator) {
this(0, comparator, false);
}
/**
* 容量无限制,用comparator排序
* @param desc true为降序
*/
public TopPriorityQueue(Comparator<? super E> comparator, boolean desc) {
this(0, comparator, desc);
}
/**
* 容量限制为capacity.超出容量限制的,会删除优先级最小(队尾).
*/
public TopPriorityQueue(int capacity) {
this(capacity, null, false);
}
public TopPriorityQueue(int capacity, boolean desc) {
this(capacity, null, desc);
}
public TopPriorityQueue(int capacity, Comparator<? super E> comparator) {
this(capacity, comparator, false);
}
public TopPriorityQueue(int capacity, Comparator<? super E> comparator, boolean desc) {
head = new LinkedItem();
last = head;
top = capacity;
this.comparator = comparator;
this.desc = desc;
}
@Override
public Iterator<E> iterator() {
// TODO 迭代器
return new It(head);
}
@Override
public int size() {
return size;
}
public boolean offer(E o) {
// TODO 添加到适当的位置
if(o == null) {
throw new IllegalArgumentException("不能添加值为null的!");
}
LinkedItem temp = new LinkedItem(o);
/*last.next = temp;
temp.prev = last;*/
if(last == head) { //第一个
last.next = temp;
temp.prev = last;
last = temp;
} else {
LinkedItem tempPrev = last;
if(comparator != null) {
while(tempPrev!=null && tempPrev != head) {
int r = comparator.compare(tempPrev.data, temp.data);
if(desc) {
r = 0 - r;
}
if(r == 1) { //tempPrev > temp
//重置,继续向前找
tempPrev = tempPrev.prev;
} else { //找到插入的位置
break;
}
}
} else if(o instanceof Comparable) { //用Comparable
while(tempPrev!=null && tempPrev != head) {
Comparable<E> tPrev = (Comparable<E>) tempPrev.data;
int r = tPrev.compareTo(temp.data);
if(desc) {
r = 0 - r;
}
if(r == 1) { //tempPrev > temp
//重置,继续向前找
tempPrev = tempPrev.prev;
} else { //找到插入的位置
break;
}
}
}
if(tempPrev != null) { //插入
if(tempPrev == last) { //后面添加的
last = temp;
}
temp.next = tempPrev.next;
if(tempPrev.next != null) {
tempPrev.next.prev = temp;
}
tempPrev.next = temp;
temp.prev = tempPrev;
}
}
size++;
if(top > 0 && size > top) { //去掉优先级最小的
tail();
}
return true;
}
/**
* 从栈底去除
*/
public E tail() {
if(last == head) {
return null;
}
LinkedItem laster = last;
last = last.prev;
last.next = null;
laster.prev = null;
size--;
return laster.data;
}
public E peek() {
// TODO 取得栈顶值
LinkedItem first = head.next;
if(first != null) {
return first.data;
}
return null;
}
public E poll() {
// TODO 从栈顶去除
LinkedItem first = head.next;
if(first != null) {
head.next = first.next;
if(first.next != null) {
first.next.prev = head;
}
size--;
return first.data;
}
return null;
}
private class It implements Iterator<E> {
LinkedItem curr;
public It(LinkedItem curr) {
super();
this.curr = curr;
}
public boolean hasNext() {
if(curr != null && curr.next != null) {
return true;
}
return false;
}
public E next() {
curr = curr.next;
E d = curr.data;
return d;
}
public void remove() {
curr.prev.next = curr.next;
if(curr.next != null) {
curr.next.prev = curr.prev;
}
size--;
}
}
/**
* @param <E>
* 链结点.
* @author chenlb 2008-5-4 下午04:48:17
*/
private class LinkedItem {
LinkedItem prev;
E data;
LinkedItem next;
public LinkedItem() {
}
public LinkedItem(E o) {
this.data = o;
}
}
}
import java.util.AbstractQueue;
import java.util.Comparator;
import java.util.Iterator;
/**
* @param <E>
* 容量capacity大于0,最多只能添加capacity个,多出的被删除掉.<br/>
* 删除时根据{@link Comparable}或{@link Comparator} 和 desc
* 如果comparator==null时使用Comparable<br/>
* non-thread safe
* @author chenlb 2008-4-23 下午11:31:06
*/
public class TopPriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private int size;
private LinkedItem head;
private LinkedItem last;
private int top; //top>0后,容量有限制
private Comparator<? super E> comparator;
private boolean desc; //降序
/**
* 容量无限制,升序.
*/
public TopPriorityQueue() {
this(0, null, false);
}
/**
* 容量无限制,
* @param desc true为降序.
*/
public TopPriorityQueue(boolean desc) {
this(0, null, desc);
}
/**
* 容量无限制,升序,用comparator排序
*/
public TopPriorityQueue(Comparator<? super E> comparator) {
this(0, comparator, false);
}
/**
* 容量无限制,用comparator排序
* @param desc true为降序
*/
public TopPriorityQueue(Comparator<? super E> comparator, boolean desc) {
this(0, comparator, desc);
}
/**
* 容量限制为capacity.超出容量限制的,会删除优先级最小(队尾).
*/
public TopPriorityQueue(int capacity) {
this(capacity, null, false);
}
public TopPriorityQueue(int capacity, boolean desc) {
this(capacity, null, desc);
}
public TopPriorityQueue(int capacity, Comparator<? super E> comparator) {
this(capacity, comparator, false);
}
public TopPriorityQueue(int capacity, Comparator<? super E> comparator, boolean desc) {
head = new LinkedItem();
last = head;
top = capacity;
this.comparator = comparator;
this.desc = desc;
}
@Override
public Iterator<E> iterator() {
// TODO 迭代器
return new It(head);
}
@Override
public int size() {
return size;
}
public boolean offer(E o) {
// TODO 添加到适当的位置
if(o == null) {
throw new IllegalArgumentException("不能添加值为null的!");
}
LinkedItem temp = new LinkedItem(o);
/*last.next = temp;
temp.prev = last;*/
if(last == head) { //第一个
last.next = temp;
temp.prev = last;
last = temp;
} else {
LinkedItem tempPrev = last;
if(comparator != null) {
while(tempPrev!=null && tempPrev != head) {
int r = comparator.compare(tempPrev.data, temp.data);
if(desc) {
r = 0 - r;
}
if(r == 1) { //tempPrev > temp
//重置,继续向前找
tempPrev = tempPrev.prev;
} else { //找到插入的位置
break;
}
}
} else if(o instanceof Comparable) { //用Comparable
while(tempPrev!=null && tempPrev != head) {
Comparable<E> tPrev = (Comparable<E>) tempPrev.data;
int r = tPrev.compareTo(temp.data);
if(desc) {
r = 0 - r;
}
if(r == 1) { //tempPrev > temp
//重置,继续向前找
tempPrev = tempPrev.prev;
} else { //找到插入的位置
break;
}
}
}
if(tempPrev != null) { //插入
if(tempPrev == last) { //后面添加的
last = temp;
}
temp.next = tempPrev.next;
if(tempPrev.next != null) {
tempPrev.next.prev = temp;
}
tempPrev.next = temp;
temp.prev = tempPrev;
}
}
size++;
if(top > 0 && size > top) { //去掉优先级最小的
tail();
}
return true;
}
/**
* 从栈底去除
*/
public E tail() {
if(last == head) {
return null;
}
LinkedItem laster = last;
last = last.prev;
last.next = null;
laster.prev = null;
size--;
return laster.data;
}
public E peek() {
// TODO 取得栈顶值
LinkedItem first = head.next;
if(first != null) {
return first.data;
}
return null;
}
public E poll() {
// TODO 从栈顶去除
LinkedItem first = head.next;
if(first != null) {
head.next = first.next;
if(first.next != null) {
first.next.prev = head;
}
size--;
return first.data;
}
return null;
}
private class It implements Iterator<E> {
LinkedItem curr;
public It(LinkedItem curr) {
super();
this.curr = curr;
}
public boolean hasNext() {
if(curr != null && curr.next != null) {
return true;
}
return false;
}
public E next() {
curr = curr.next;
E d = curr.data;
return d;
}
public void remove() {
curr.prev.next = curr.next;
if(curr.next != null) {
curr.next.prev = curr.prev;
}
size--;
}
}
/**
* @param <E>
* 链结点.
* @author chenlb 2008-5-4 下午04:48:17
*/
private class LinkedItem {
LinkedItem prev;
E data;
LinkedItem next;
public LinkedItem() {
}
public LinkedItem(E o) {
this.data = o;
}
}
}
评论
5 楼
moshalanye
2008-07-01
lucene 2.32 中用来实现查询结果存放缓存的时候 在代码里有一个这样的实现可以去看下得
org.apache.lucene.util.PriorityQueue 这个是抽象类,里面也有它的实现
org.apache.lucene.util.PriorityQueue 这个是抽象类,里面也有它的实现
4 楼
stephen
2008-06-12
引用
于是,在有空的时间里写了一下。内容是一个双向链表(带头的,头不作保存数据),用插入排序。个人认为一个个添加的用插入排序效果比较好。从队尾到队头找合适的插入位置,是稳定的排序。
这样来看,这个就是一个排序的双向链表而已。当然,由于有了排序,也可以当作优先队列来用。只是要看数据的规模,这种双向链表的插入在数据量比较大的情况下,需要做的比较次数太多了。
算法书上通常会提到用 heap 结构来实现优先队列,主要是考虑在大规模的数据量情况,heap 是一种性能比较好的结构,在优先队列的使用场景中比二叉树更好一点。
3 楼
llade
2008-06-12
取决于你需要解决的问题,插入排序用TreeSet。
插入和移除手段可以多样,真正要关注的是否需要多线程访问。
插入和移除手段可以多样,真正要关注的是否需要多线程访问。
2 楼
chenlb
2008-05-25
现在我用的是插入排序,链表的.
1 楼
chenlb
2008-05-25
或许已经有第三方的库类似实现,各位朋友推荐下。
发表评论
-
不抛出越界异常的求子串方法
2008-06-18 14:36 1216用String.substring方法,不小心会有越界异 ... -
java -D参数简化加入多个jar
2008-05-30 11:22 1988java命令引入jar时可以-cp参数,但时-cp不 ... -
poi会中文乱码,Jexcelapi不会
2007-03-21 19:06 2269目前比较流行的生成Excel文件的有poi和Jexcelapi ... -
itest生成pdf中文为空白
2007-03-21 19:52 2565要下载iTextAsian.jar地址: http://prd ... -
[转载]jsp 实现 word, excel
2007-08-22 13:15 1493这里使用一个小技巧,就是先将其转换为可编辑的JSP文件,然后再 ... -
jsp 提交表单中文问题解决
2007-09-09 09:47 1459用过虑器,但只对post有效,get方式请看。http ... -
Weblogic 中部署 Web 应用程序
2007-09-22 18:48 34191、安装好weblogic8.1 2、 ... -
weblogic 8.1.4服务器挂起,出现StuckThreadMaxTime错误
2007-10-06 21:10 9042前几天用spring+hibernate+struts写了个增 ... -
weblogic8.1作为windows服务运行
2007-10-06 23:02 1652实验室机房里安装的Weblogic 每次想打开网页 ... -
jsp 下载文件
2007-10-16 23:57 2012jsp 直接输出二进制文件怎么办呢? downl ... -
java 压缩目录为 zip
2007-10-18 13:53 2114用java好久了,还没有写个压缩文件的示例,昨晚弄 ... -
jstl 1.0 formatDate yyyy-mm 不能正常工作
2007-10-25 22:38 1104jstl 1.0 formatDate yyyy-m ... -
jxl 写 excel
2007-10-29 10:52 1321项目中要写excel,把这个例子写出来,以后可以看 ... -
jxl 读 excel
2007-10-29 11:04 1462与写对应的是读. package net.bl ... -
ant build 出现 warning modified in the future
2007-12-13 23:13 1747今天同学想rebuild项目源码,但出现上面情况。 ... -
ant 编译特定包下面的源文件
2007-12-15 12:13 1712项目中有applet,现在想只编译applet包下 ... -
生产者-消费者
2008-01-24 11:36 1253这学期,应聘的时候有一些是线程相关的,虽然自己对线程编 ... -
Java读RTF乱码问题
2008-02-01 17:05 6897这几天想用Java读富文档。用javax.swing. ... -
System.in重复接收用户输入一行命令
2008-03-11 21:49 1650以前想用循环来System.in (或是其它输入方式老 ... -
下载文件保存提示文件名显示中文
2008-03-16 14:29 1192用URLEncoder转换。 String file ...
相关推荐
在Java编程中,优先队列(PriorityQueue)是一种特殊的队列,它按照元素的优先级进行出队。这种数据结构在实现多路归并排序(Multi-Merge Sort)时非常有用,因为它能有效地处理多个已排序的输入流,并将它们合并成...
Java中处理这类问题通常涉及到哈希表(HashMap)和优先队列(PriorityQueue)的数据结构。哈希表用于存储元素及其出现次数,而优先队列用于找出频率最高的元素。优先队列的特性是总是保持最小的元素在队列头部,这...
这个过程可以使用优先队列(PriorityQueue)来实现,队列中的元素是自定义的Node类,包含字符、频率以及指向左子节点和右子节点的引用。 3. **遍历哈夫曼树生成编码**:从根节点开始,每向左走一步记录一个0,每向...
* PriorityQueue:基于堆结构实现,可以用它来实现优先队列。 Map Map 是一种键值对的映射表,提供了对键值对操作的基本方法。常见的 Map 实现类有: 1. TreeMap:基于红黑树实现。 2. HashMap:基于哈希表实现...
Java的`PriorityQueue`类实现了优先队列。 5. **集合和映射表**: Java集合框架包括List、Set和Map接口,以及它们的各种实现类,如ArrayList、LinkedList、HashSet、TreeSet、HashMap和TreeMap等。这些集合类提供了...
7. **数据结构与算法**:在Java实现中,常用的数据结构包括数组、链表、队列、栈、优先队列等。算法方面,除了上述提到的路径搜索算法,还需要理解动态规划、回溯、递归等概念。 8. **编程技巧**:良好的代码组织和...
在Java中实现Prim算法,通常有两种方法:优先队列(PriorityQueue)和邻接矩阵(Adjacency Matrix)。下面将详细介绍这两种方法,并通过代码实例来阐述它们的工作原理。 1. **优先队列方法**: 使用优先队列可以...
- 高级集合:优先队列PriorityQueue、并发集合ConcurrentHashMap等。 5. **多线程** - 创建线程:通过实现Runnable接口或继承Thread类。 - 线程同步:synchronized关键字、wait/notify机制、Lock接口(如...
这个过程可以通过优先队列(如堆)来实现,每次取出权值最小的两个节点进行合并。 2. **生成编码**:从根节点到每个叶子节点的路径可以形成一个独特的二进制编码。左分支通常代表0,右分支代表1。当遍历到叶子节点...
`PriorityQueue`则是一种优先队列,根据元素的自然顺序或比较器进行排序。 `Map`接口存储键值对,不允许键重复。`HashMap`是基本的实现,它通过哈希表提供快速的插入、删除和查找操作。`TreeMap`使用红黑树保持键的...
`Queue`接口的实现如`PriorityQueue`基于堆实现,可以实现优先级队列功能。 `Map`接口代表键值对的集合,主要实现类有`HashMap`、`TreeMap`、`HashTable`和`LinkedHashMap`。`HashMap`在Java 7中基于哈希表(冲突...
- 使用优先队列(PriorityQueue)存储节点,根据频率排序,便于每次取出频率最小的两个节点。 - 构建哈夫曼树后,可以通过深度优先搜索(DFS)或广度优先搜索(BFS)生成编码表。 - 压缩时,根据编码表将文本转换...
`PriorityQueue.h` 文件定义了优先级队列的实现,支持以下功能: - **构造与析构**:初始化和销毁优先级队列。 - **入队**:向队列中添加元素。 - **出队**:移除并返回优先级最高的元素。 - **获取最高优先级元素*...
5. **队列的变种:优先队列**:优先队列根据优先级顺序处理元素,可以使用Java的PriorityQueue类来实现。 6. **堆**:堆是一种特殊的树形数据结构,通常为完全二叉树,满足堆性质(父节点的值大于或小于子节点的值...
在Java中,我们可以使用优先队列来实现贪心算法。首先,我们将所有的果子数加入优先队列,然后不断地从队列中取出两个最小的元素,合并它们,并将合并的结果加入队列中。最后,我们将所有的果子合并成一堆,并计算出...
Java的`java.util.PriorityQueue`实现了最小堆,常用于优先级任务的调度。 6. **哈希表(Hash Table)**:哈希表通过哈希函数将键映射到数组的索引上,实现快速查找。Java的`HashMap`和`HashTable`是典型的哈希表...
这个过程包括创建一个最小堆(优先队列)并逐步合并频率最低的两个节点,直到只剩下一个节点,即为Huffman树的根节点。每个内部节点代表一个合并的字符或子树,而叶子节点则对应原始字符。 3. **生成Huffman编码**...
在Java中实现这两个问题,我们可以利用HashMap类处理单词计数,PriorityQueue类实现优先队列,以及gcd()函数计算最大公约数。在实际编程中,理解并熟练应用这些数据结构和算法能够有效提高代码质量和效率。 总结,...
在实现过程中,可能需要考虑优化算法性能,比如使用优先队列(PriorityQueue)来存储待分配的比赛,或者使用动态规划来减少回溯搜索。同时,为了处理时间冲突,可以设计一个回溯函数,当发现无法分配比赛时,回溯并...