一、优先队列
1.优先队列的定义
优先队列分为优先最大或者优先最小,用堆实现优先队列是最高效的方式。而存储堆的最高效时间最短的为用数组存储。注意如果需要索引或者索引值与数组下标差别太大,则可以在堆数组元素存索引值。
2.优先队列的用处
可以迅速找出一组数据的最大或者最小的部分,不需要在对数组进行排序,因此可以适用于高数据量
3.Java实现优先最大/最小队列代码如下
import java.*;
class MaxPQ{
private int []pq;
@SuppressWarnings("unused")
private int N=0;
public MaxPQ(int maxN) {
pq=new int [maxN+1];
}
public void Insert(int n) {
pq[++N]=n;
swim(N);
}
public void print() {
for(int i=1;i<=N;i++) {
System.out.print(pq[i]+" ");
}
}
public int delMax() {
int max= pq[1];
exch(1, N--);
sink(1);
return max;
}
public void sort() {
int L=pq.length;
for(int i=L/2;i>=1;i--) {
sink(i);
}
while(L>1) {
exch(1,L--);
sink(L);
}
}
private void swim(int k) {
while(k>1&&less(k/2, k))
{
exch(k/2, k);
k=k/2;
}
}
private void sink(int k) {
int j=0;
while(2*k<N) {//注意这个为子女小于N即可
j=2*k;
if(less(j, j+1)) {
j=2*k+1;
}
if(!less(k, j)) {
break;
}
exch(k, j);
k=j;
}
}
@SuppressWarnings("unused")
private boolean less(int i,int j) //若要变成最小堆只需把这个函数改成pq[i]>pq[j]?true:false;
{
return pq[i]<pq[j]?true:false;
}
private void exch(int i,int j) {
int t=pq[i];
pq[i]=pq[j];
pq[j]=t;
}
}
public class Main {
public static void main(String args[]) {
MaxPQ a=new MaxPQ(5);
a.Insert(1);
a.Insert(9);
a.Insert(4);
a.print();
}
}
注意:若要改成最小堆,只需把less这个函数改成pq[i]>pq[j]?true:false;即可
二、并查表
并查表其实就包括两个功能,一个是并(Union),一个便是查即查根节点(FindFather),所以这两个功能实现函数如下:
public class Main(){
private int []father=new int [1000];//用于存放每一个结点的父节点
public int Findfather(int x){//查找元素x所在的根节点集合
int a=x;
while (x!=father[x]){
x=father[x];}
//下面为压缩路径,可以不写
while(a!=father[a]){
int z=a;
a=father[a];//继续找下一个父节点
fathr[z]=x;//将该节点的父节点改成x
}
return x;
}
public int Union(int a,int b){
int faA=Findfather(a);
int faB=Findfather(b);
if(faA!=faB){
father[faA]=faB;
}
}