简单解释优先队列,即为在队列之中呢,元素被赋予了优先级,实现了优先级高的先出.

对于其,我们先定义API接口

常见方法: delMax()删除最大元素 insert()插入元素

还有比较元素 less()

图片

图片

对于其实现

可以分别使用4种基本数据结构是实现优先队列的起点,可以分别使用有序的或者无序的数组或者链表去实现,

1.无序数组实现

实现删除最大元素的时候,我们添加一段类似选择排序的内循环,让最大元素和边界交换并删除

2.有序数组实现

在insert中添加diamante,使较大的元素都向右移动以一格,方便我们之后方法的调用

3.链表实现

基于链表的下压栈,然后修改pop来返回最大元素

最有的实现方式,是我们使用二叉堆来实现优先队列

二叉堆本质上是一个二叉树,每个父结点都要大于等于两个子节点,这就是堆有序

根节点是其最大的结点

二叉堆的顺序可以为,自上而下,自左往右,在每个结点下面连接两个小的节点.

每个元素都有三个节点,一个父节点和两个子节点

实现它的方法很简单,只要一个数组,根节点在索引1,其子节点在 2,3,子节点的子节点在5,6,7

二叉树构造的数组索引0位置不使用

二叉树的结构很严格,但我们仍可以实现插入元素和删除最大元素

如果堆的有序性因为某个结点的变化而改变

结点变得更大,就循环交换他和他的父节点来修复堆结构,

图片

我们称为上浮;

如果结点变得更小,就循环交换他和他的子节点来修复堆结构,

对应的就是下沉

删除最大元素的时候,直接让最大元素和最小的元素进行交换并删除,这样打破了规则,然后我们重新下沉排序

图片

public class Priority_Queue_Binary_Tree<Key extends Comparable<Key>>{

private Key[] pq;//静态数组

private int N = 0;

public void MaxPQ(int maxN) {

pq  = (Key[])new Comparable[maxN+1];//创建一个 大于N 1的数组

N = maxN;//N为数组的数量

}

public boolean isEmpty() {

return N==0;

}

public int size() {

return N;

}

public void insert(Key input) {//插入

pq[++N] = input;

swim(N);//进行排序

}

public Key delMax(){//输出最大

Key max = pq[1];//获取

exch(pq, 1, N–);//交换

pq[N++] = null;//防止溢出

sink(1);//向下排序

return max;//输出

}

private void swim(int k) {

while(k>1&&less(pq[k/2], pq[k])) {//如果大于1,且比父节点大

exch(pq, k/2, k);//交换

k = k/2;//递归

}

}

private void sink(int k) {

while (2*k<=N) {//子节点小于数组

int j= 2*k;

if (j<N &&less(pq[j], pq[j+1])) {//只要不溢出且比子节点小

j++;//加大索引

}

while (!less(pq[k], pq[j]))

break;//如果大于则退出

exch(pq, k, j);//交换

k = j;//然后递归

}

}

public static boolean less(Comparable a, Comparable a2) {// 对元素进行比较

return a.compareTo(a2) < 0;

}

private static void exch(Comparable[] a, int i, int j) {// 进行交换

Object n = a[i];

a[i] = a[j];

a[j] = (Comparable<Object>) n;

}

}

他的插入和删除实现即:

插入时候直接插到最后面,然后上浮

删除则是最后一个和第一个进行交换,然后输入原第一位的最大元素,

把现第一位的元素进行下沉,还把N+1的值设置为Null,进行收回空间

发表评论

邮箱地址不会被公开。 必填项已用*标注