二叉堆的数组实现

package com.hengyunsoft.test;

import java.util.Comparator;
import java.util.Random;

import edu.emory.mathcs.backport.java.util.Arrays;

public class PriorityArray<E> {

/**
* 当前已用大小
*/
private int size;

private Object[] e;

private Comparator<E> comparator;

public PriorityArray(int capacity, Comparator<E> comparator) {

e = new Object[capacity];
this.comparator = comparator;
size = 0;
}

/**
*
* @param obj
* not null
*/
public void put(E obj) {

if (obj == null)
return;
e[size] = obj;
swapFZ(size);
++size;
}

private void swapFZ(int children) {
if (children <= 0) {
return;
}

// 找父节点
// 左:left = 2p+1
// 右:left = 2p+2
int p;
if ((children & 1) == 1) {
// 奇数
p = (children - 1) >>> 1;
} else {
// 偶数
p = (children - 2) >>> 1;
}

System.out.print("孩子:" + children + " value :" +(E) e[children]);
System.out.print(" 父亲:" + p + " value :" +(E) e[p]);
if (comparator.compare((E) e[children], (E) e[p]) < 0) {
swap(children, p);
System.out.println("进行交互");
swapFZ(p);
} else {
System.out.println("不会进行交互");
}
}

private void swap(int x, int y) {
final Object temp = e[x];
e[x] = e[y];
e[y] = temp;
}

public static void main(String[] args) {

System.out.print(1 << 1 + 1);

PriorityArray<Integer> arr = new PriorityArray<>(100,
new Comparator<Integer>() {

@Override
public int compare(Integer x, Integer y) {
return Integer.compare(x, y);
}
});

Random random = new Random();

for (int i = 0; i < arr.e.length; i++) {
arr.put(random.nextInt(10000));
}



for (int j = 0,nextFlag=1,i=0; j < arr.size; j++) {
if(j < nextFlag){
System.out.print(arr.e[j] + " ");

}else {

System.out.println();
System.out.print(arr.e[j] + " ");

nextFlag += 2 << i;
i++;
}
}
System.out.println();
System.out.println(Arrays.toString(arr.e));
for (int i = 0; i < arr.e.length; i++) {
System.out.print(arr.pop() + " ");
}
}

public E pop() {

if (size == 0)
return null;
E result = (E) e[0];

e[0] = e[size - 1];
swapZF(0);
--size;
return result;
}

private void swapZF(int p) {

final int left = (p << 1) + 1;
final int right = left + 1;
if (left >= size) {
return;
}
if (right >= size) {
if (comparator.compare((E) e[left], (E) e[p]) < 0) {
swap(left, p);
swapZF(left);
}
return;
}

int minIndex = right;
if (comparator.compare((E) e[left], (E) e[right]) < 0) {
minIndex = left;
}

if (comparator.compare((E) e[minIndex], (E) e[p]) < 0) {
swap(minIndex, p);
swapZF(minIndex);
}
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C语言中实现优先队列的经典方式是使用二叉堆数据结构。二叉堆是一种完全二叉树,同时满足堆次序的条件。在二叉堆中,每个节点的值都大于或等于其子节点的值(最大堆),或者每个节点的值都小于或等于其子节点的值(最小堆)。通过维护堆次序,可以保证堆顶元素是最大或最小的元素。 下面是C语言中实现二叉堆的优先队列的一种方法: ```C #include <stdio.h> #include <stdlib.h> typedef struct { int capacity; // 队列的容量 int size; // 队列中元素的数量 int *data; // 存储队列元素的数组 } PriorityQueue; PriorityQueue* createPriorityQueue(int capacity) { PriorityQueue *queue = (PriorityQueue*)malloc(sizeof(PriorityQueue)); queue->capacity = capacity; queue->size = 0; queue->data = (int*)malloc(sizeof(int) * capacity); return queue; } void destroyPriorityQueue(PriorityQueue *queue) { free(queue->data); free(queue); } void enqueue(PriorityQueue *queue, int value) { if (queue->size >= queue->capacity) { // 队列已满,需要扩容 queue->capacity *= 2; queue->data = (int*)realloc(queue->data, sizeof(int) * queue->capacity); } // 将元素放入队列尾部 queue->data[queue->size] = value; queue->size++; // 通过向上调整操作恢复堆次序 int child = queue->size - 1; int parent = (child - 1) / 2; while (child > 0 && queue->data[child] > queue->data[parent]) { int temp = queue->data[child]; queue->data[child] = queue->data[parent]; queue->data[parent] = temp; child = parent; parent = (child - 1) / 2; } } int dequeue(PriorityQueue *queue) { int value = queue->data[0]; // 将队尾元素放到队首,并删除队尾元素 queue->data[0] = queue->data[queue->size - 1]; queue->size--; // 通过向下调整操作恢复堆次序 int parent = 0; while (parent * 2 + 1 < queue->size) { int leftChild = parent * 2 + 1; int rightChild = parent * 2 + 2; int maxChild = leftChild; if (rightChild < queue->size && queue->data[rightChild] > queue->data[leftChild]) { maxChild = rightChild; } if (queue->data[parent] >= queue->data[maxChild]) { break; } int temp = queue->data[parent]; queue->data[parent] = queue->data[maxChild]; queue->data[maxChild] = temp; parent = maxChild; } return value; } int main() { PriorityQueue *queue = createPriorityQueue(10); enqueue(queue, 5); enqueue(queue, 3); enqueue(queue, 7); printf("%d\n", dequeue(queue)); // 输出7,因为7是队列中的最大值 printf("%d\n", dequeue(queue)); // 输出5,因为5是队列中的次大值 printf("%d\n", dequeue(queue)); // 输出3,因为3是队列中的最小值 destroyPriorityQueue(queue); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值