当前位置:网站首页>优先队列
优先队列
2022-08-10 05:32:00 【cbys-1357】

public class MaxPriorityQueue<T extends Comparable<T>> {
//存储堆中的元素
private T[] items;
//记录堆中元素的个数
private int N;
public MaxPriorityQueue(int capacity){
this.items=(T[]) new Comparable[capacity+1];
this.N=0;
}
// 判断堆中索引i处的元素是否小于索引j处的元素
private boolean less(int i,int j) {
return items[i].compareTo(items[j])<0;
}
// 交换元素
private void exch(int i,int j) {
T tmp=items[i];
items[i]=items[j];
items[j]=tmp;
}
// 判断堆中的元素是否为空
public boolean isEmpty() {
return this.N==0;
}
// 返回堆中元素个数
public int size() {
return this.N;
}
// 往堆中插入一个元素
public void insert(T t) {
items[++N]=t;
swim(N);//让元素t上浮
}
// 使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置
private void swim(int k) {
//如果已经到了根结点,就不需要循环了
while(k>1) {
//比较当前结点和其父结点
if(less(k/2,k)) {
//父结点小于当前结点,需要交换
exch(k/2,k);
}
k=k/2;
}
}
//删除堆中最大的元素,并返回这个最大元素
public T delMax() {
T max=items[1];
//交换当前结点和其父结点
exch(1,N);
//删除最后位置上的元素
items[N]=null;
//个数-1
N--;
sink(1);
return max;
}
//使用下沉算法,使索引k处的元素能在堆中处于一个正确的位置
private void sink(int k) {
//如果当前已经是最底层了,就不需要循环了
while(2*k<=N) {
//找到子结点中的较大者
int max;
//若右子结点存在,找到子结点最大值
if(2*k+1<=N) {
if(less(2*k,2*k+1)) {
max=2*k+1;
}else {//右结点不存在,直接将左结点点赋值给最大值
max=2*k;
}
}else {
max=2*k;
}
//比较当前结点和子结点中的较大者,如果当前结点不小,则结束循环
if(!less(k,max)) {
break;
}
//当前结点小,则交换,
exch(k,max);
k=max;
}
}
}
测试类:
public class MaxPriorityQueueTest {
public static void main(String[] args) {
MaxPriorityQueue<String> queue=new MaxPriorityQueue<String>(8);
queue.insert("f");
queue.insert("g");
queue.insert("j");
queue.insert("c");
queue.insert("m");
queue.insert("a");
queue.insert("q");
queue.insert("t");
String s;
while(!queue.isEmpty()) {
s=queue.delMax();
System.out.print(s+"\t");
}
}
}
2.最小优先队列

代码实现:
public class MinPriorityQueue<T extends Comparable<T>> {
//存储堆中的元素
private T[] items;
//记录堆中元素的个数
private int N;
// 构造方法
public MinPriorityQueue(int capacity) {
this.items=(T[]) new Comparable[capacity+1];
this.N=0;
}
//判断堆中索引i处的元素是否小于索引j处的元素
private boolean less(int i,int j) {
return items[i].compareTo(items[j])<0;
}
// 交换元素
private void exch(int i,int j) {
T tmp=items[i];
items[i]=items[j];
items[j]=tmp;
}
// 判断堆中的元素是否为空
public boolean isEmpty() {
return this.N==0;
}
// 返回堆中元素个数
public int size() {
return this.N;
}
// 往堆中插入一个元素
public void insert(T t) {
items[++N]=t;
swim(N);
}
//使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置
private void swim(int k) {
//如果没有父结点,则不再上浮
while(k>1) {
//如果当前结点比父结点小,则交换
if(less(k,k/2)) {
exch(k,k/2);
}
k=k/2;
}
}
//删除堆中最小的元素,并返回这个最小元素
public T delMin() {
//索引1处的值是最小值
T min=items[1];
//交换索引1处和索引N处的值
exch(1,N);
//删除索引N处的值
items[N]=null;
//数据元素-1
N--;
//对索引1处的值做下沉,使堆重新有序
sink(1);
//返回被删除的值
return min;
}
//使用下沉算法,使索引k处的元素能在堆中处于一个正确的位置
private void sink(int k) {
//如果没有子结点,则不再下沉
while(2*k<=N) {
//找出子结点中的较小值的索引
int min;
if(2*k+1<=N) {
if(less(2*k,2*k+1)) {
min=2*k;
}else {
min=2*k+1;
}
}else {
min=2*k;
}
//如果当前结点小于子结点中的较小值,则结束循环
if(!less(min,k)) {
break;
}
//当前结点大,交换
exch(min,k);
k=min;
}
}
}
测试代码:
public class MaxPriorityQueueTest {
public static void main(String[] args) {
MaxPriorityQueue<String> queue=new MaxPriorityQueue<String>(8);
queue.insert("f");
queue.insert("g");
queue.insert("j");
queue.insert("c");
queue.insert("m");
queue.insert("a");
queue.insert("q");
queue.insert("t");
String s;
while(!queue.isEmpty()) {
s=queue.delMax();
System.out.print(s+"\t");
}
}
}





public class IndexMinPriorityQueue<T extends Comparable<T>> {
//存储堆中的元素
private T items[];
//保存每个元素在items数组中的索引,pq数组需要堆有序
private int pq[];
//保存qp的逆序,pq的值作为索引,pq的索引作为值
private int qp[];
//记录堆中元素的个数
private int N;
//构造方法
public IndexMinPriorityQueue(int capacity) {
this.items=(T[]) new Comparable[capacity+1];
this.pq=new int[capacity+1];
this.qp=new int[capacity+1];
this.N=0;
for(int i=0;i<qp.length;i++) {
qp[i]=-1;
}
}
//获取队列中元素的个数
public int size() {
return this.N;
}
//判断队列是否为空
public boolean isEmpty() {
return this.N==0;
}
//判断堆中索引i处的元素是否小于索引j处的元素
private boolean less(int i,int j) {
return items[pq[i]].compareTo(items[pq[j]])<0;
}
//交换堆中i索引和j索引处的值
private void exch(int i,int j) {
//先交换pq数组中的值
int tmp=pq[i];
pq[i]=pq[j];
pq[j]=tmp;
//更新qp数组中的值
qp[pq[i]]=i;
qp[pq[j]]=j;
}
//判断k对应的元素是否存在
public boolean contains(int k) {
return qp[k]!=-1;
}
//最小元素关联的索引
public int minIndex() {
//pq的索引1处,存放的是最小元素在items中的索引
return pq[1];
}
//往队列中插入一个元素,并关联索引i
public void insert(int i,T t) {
//如果索引i处已经存在了元素,则不让插入
if(contains(i)) {
throw new RuntimeException("该索引已经存在");
}
//个数+1
N++;
//把元素存放到items数组中
items[i]=t;
//使用pq存放i这个索引
pq[N]=i;
//在qp的i索引处存放N
qp[i]=N;
//上浮items[pq[N]],让pq堆有序
swim(N);
}
//删除队列中最小的元素,并返回该元素关联的索引
public int delMin() {
//找到items中最小元素的索引
int minIndex=pq[1];
//交换pq中索引1处的值和N处的值
exch(1,N);
//删除qp中索引pq[N]处的值
qp[pq[N]]=-1;
//删除pq中索引N处的值
pq[N]=-1;
//删除items中的最小元素
items[minIndex]=null;
//元素数量-1
N--;
//对pq[1]做下沉,让堆有序
sink(1);
return minIndex;
}
//删除索引i关联的元素
public void delete(int i) {
//找出i在pq中的索引
int k=qp[i];
//把pq中索引k处的值和索引N处的值交换
exch(k,N);
//删除qp中索引pq[N]处的值
qp[pq[N]]=-1;
//删除pq中索引N处的值
pq[N]=-1;
//删除items中索引i处的值
items[k]=null;
//元素数量-1
N--;
//对pq[k]做上浮,让堆有序
swim(k);
//对pq[k]做下沉,让堆有序
sink(k);
}
//把与索引i关联的元素修改为为t
public void changeItem(int i,T t) {
//修改items数组中索引i处的值为t
items[i]=t;
//找到i在pq中的位置
int k=qp[i];
//对pq[k]做上浮,让堆有序
swim(k);
//对pq[k]做下沉,让堆有序
sink(k);
}
//使用上浮算法,使索引k处的元素能在堆中处于一个正确的位置
private void swim(int k) {
//如果已经到了根结点,则结束上浮
while(k>1) {
//比较当前结点和父结点,如果当前结点比父结点小,则交换位置
if(less(k,k/2)) {
exch(k,k/2);
}
k=k/2;
}
}
//使用下沉算法,使索引k处的元素能在堆中处于一个正确的位置
private void sink(int k) {
//如果当前结点已经没有子结点了,则结束下沉
while(2*k<=N) {
//找出子结点中的较小值
int min;
if(2*k+1<=N) {
if(less(2*k,2*k+1)) {
min=2*k;
}else {
min=2*k+1;
}
}else {
min=2*k;
}
//如果当前结点的值比子结点中的较小值小,则结束下沉
if(less(k,min)) {
break;
}
exch(min,k);
k=min;
}
}
}
边栏推荐
猜你喜欢
随机推荐
matlab中的常用的类型转换
Knowledge Distillation Thesis Learning
view【】【】【】【】
PCL点云配准--ICP or keypoints+features
来亲自手搭一个ResNet18网络
链读 | 最新最全的数字藏品发售日历-07.28
cesium 旋转图片
十年磨一剑!数字藏品行情软件,链读APP正式开放内测!
Chain Reading | The latest and most complete digital collection calendar-07.28
深度学习中的学习率调整策略(1)
el-dropdown drop-down menu style modification, remove the small triangle
链读好文:Jeff Garzik 推出 Web3 制作公司
error in ./node_modules/cesium/Source/ThirdParty/zip.js
IDEA连接MySQL数据库并执行SQL查询操作
用Pytorch从0到1实现逻辑回归
Mini Program Study Notes: Communication between Mini Program Components
Set Sources Resources and other folders in the IDEA project
wiki confluence installation
Content related to ZigBee network devices
Module build failed TypeError this.getOptions is not a function报错解决方案








