优先队列的实现--二叉堆

// 二叉堆 -- 用于优先队列的实现
// 完全二叉树的 I 结点的 两个 child 是 I*2 and I*2+1 . --二叉树的性质
// 完全二叉树的 I 结点的 father 是 I/2 .  --二叉树的性质
// 队列结构 -> head -> queue -> bottom -> 
// head in, bottom out
// 
/*
test data 一共10个数字 输入输出的时候需要更改 
12
8
3
5
6
7
15
1 
10
9
Output:1 3 5 6 7 8 9 10 15
*/
#include <cstdio>
#include <iostream>
using namespace std;

const int MAXQ = 10000;
int head; // 只需要队列入口的指向   

int prority_queue[MAXQ];


void swap(int& a,int& b){
	a^=b^=a^=b;
}


bool is_empty(){
	return head - 1;
}

void InQueue(int a){
	int node = head;
	int father = node /2 ; // /2
	prority_queue[head++] = a;
	while(prority_queue[node] < prority_queue[father]){
		swap(prority_queue[node], prority_queue[father]);
		node = father;
		father = node /2 ; // /2
	}
	 // ensure right child bigger than left child, impossible!!

}

int DeQueue(){
	int val = prority_queue[1]; // the bottom of queue 
	int node = 1;
	int temp_head = prority_queue[--head]; // let the head element out queue
	while(node*2 < head){
		int temp_node = node; // save father node
		node = node << 1; // *2
		if (node+1 == head || prority_queue[node] < prority_queue[node+1]) // choose the smaller rise
			swap(prority_queue[node],prority_queue[temp_node]);
		else{ // 可以再优化
			swap(prority_queue[node+1],prority_queue[temp_node]);
			node = node + 1;
		}
	}
	prority_queue[node] = temp_head; // make the original element into the blank site
	int father = node /2 ; // /2  adjust the element to a appropriate site
	while(prority_queue[node] < prority_queue[father]){
		swap(prority_queue[node], prority_queue[father]);
		node = father;
		father = node /2 ; // /2
	}
	prority_queue[head] = 0;

	return val;
}

void init(){
	head = 1; // queue start with '1'
	memset(prority_queue,0,sizeof(prority_queue));
	int n,a;
	n = 10;
	for (int i = 0 ; i < n ;i++){
		cin >> a;
		InQueue(a);
	}

}

int main()
{
//	freopen("in.txt","r",stdin);
	init();

	for (int i = 0 ; i < 10 ;i++){
		cout << DeQueue() << " ";
	}

	return 0;
}


HDU1102(最小生成树prime算法) 这个题目写了一下午+一晚上,一开始还没有了解过stl里面的优先队列是怎么实现的,于是就去看了看关于优先队列的实现。才知道优先队列是可以用二叉堆实现的(附上人家的连接: 二叉堆),然后就手写了一个int型的优先队列,于是我就想着看来离AC不远了,然后当回过头来看题目的时候发现按我的思路数据居然用一个数组放不下,看来还得结构体,于是把int型的改成了结构体的,然后又发现按我的思路这个图还应带有方向,然后又改成有向图。就这样改来改去,还带点小粗心。直到刚刚才给ac了。
  • 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、付费专栏及课程。

余额充值