优先队列及其基本操作的堆实现

用代码说话

/*
	本代码实现优先队列:分为最大优秀队列和最小优先队列
	优先队列用于维护一组元素构成的集合S的数据结构,其中的
	每一个元素都有一个相关的值,称为关键字。
	一个最大优先队列支持以下操作:
		insert(S,x)向S中插入元素x;
		maximum(S)返回S中的最大键值元素;
		extract-max(S)去掉并且返回S中的最大键值元素;
		increase-key(S,x,k)将元素x的关键字增加到k,假设k要不小于x的原关键字

	一个最小优先队列支持以下操作:
		insert(S,x)向S中插入元素x;
		minimum(S)返回S中的最小键值元素;
		extract-min(S)去掉并且返回S中的最小键值元素;
		decrease-key(S,x,k)将元素x的关键字减小到k,假设k要不大于x的原关键字

	最大优先队列可以应用与操作系统的作业调度
	最小优先队列可以用于基于事件驱动的模拟器
	本文将实现最大优先队列
	优先队列可以用堆来实现
*/

#include<stdio.h>
#include<stdlib.h>
#define N 6

static int heapSize=N;
/*
    返回父节点和子节点索引
*/
//返回父结点
int parent(int index)
{
    return (index-1)/2;
}
 
//返回左孩子
int left(int index)
{
    return (index<<1)+1;
}
 
//返回右孩子
int right(int index)
{
    return (index+1)<<1;
}

/*
    维护堆的性质,即把不符合要求的元素重新组织
    时间复杂度为logn
*/
int maxHeapify(int *A,int index,int size)
{
    int L=left(index);
    int R=right(index);
    int tmp;
    int largestIndex;
    if(L<size && *(A+index)<*(A+L)) {
        largestIndex=L;
    } else {
	largestIndex=index;
    }
    if(R<size && *(A+largestIndex)<*(A+R)) {
        largestIndex=R;
    }
    if(index!=largestIndex) {
        tmp=*(A+index);
        *(A+index)=*(A+largestIndex);
        *(A+largestIndex)=tmp;
        maxHeapify(A,largestIndex,size);
    }
    return 0;
}

/*
    对除没有子结点的结点进行堆的维护操作,进而
    使得一个数组变成一个最大堆
    时间复杂度为nlogn
*/
int buildMaxHeap(int *A)
{
    int size=N;
    //找出不是叶子结点的最后一个索引
    int need=heapSize/2-1;
    int i;
    for(i=need;i>=0;i--) {
        maxHeapify(A,i,heapSize);
    }
    return 0;
}

/*
    堆排序程序
    通过根元素始终是最大的,因此我们倒过来找
    从最大的元素依次往最小的元素去排序
*/
int heapSort(int *A)
{
    buildMaxHeap(A);
    int j;
    int size=heapSize;
    int i;
    int tmp;
    for(i=N-1;i>=1;i--) {
        tmp=*A;
        *A=*(A+i);
        *(A+i)=tmp;
        size--;
        maxHeapify(A,0,size);
    }
    return 0;
}

//------------------以下为优先队列的操作-----------------------//

/*
	返回堆的最大值
*/
int heapMaxElement(int *A)
{
	return A[0];
}

/*
	获取堆的最大值并移除该最大值
*/
int heapExtractMax(int *A)
{
	if(N<1) {
		printf("Heap error!");
	}
	int max=heapMaxElement(A);
	A[0]=A[heapSize-1];
	heapSize=heapSize-1;
	maxHeapify(A,0,heapSize);
	return max;
}

/*
	增加第i个元素的值,然后重新构建堆
*/
int heapIncreaseKey(int *A,int index,int newValue) 
{
	if(newValue<*(A+index)) {
		printf("新增加的值应该要比原值大!");
		return 1;
	}
	*(A+index)=newValue;
	while(index>0&&*(A+index)>*(A+parent(index))) {
		int temp;
		temp=*(A+index);
		*(A+index)=*(A+parent(index));
		*(A+parent(index))=temp;
		index=parent(index);
	}
	return 0;
}

/*
	向最大堆中插入元素
*/
int heapInsert(int *A,int key)
{
	heapSize=heapSize+1;
	int *b=malloc(sizeof(int)*heapSize);
	b=A;
	*(b+heapSize-1)=key-1;
	heapIncreaseKey(b,heapSize-1,key);
	A=b;
	return 0;
}

int main()
{
	int b[N]={2,1,3,2,5,4};
	int* a=b;
	//必做:构建最大堆
	buildMaxHeap(a);
	printf("增加第一个元素的值为6\n");
	heapIncreaseKey(a,0,6);
	printf("%d\n",*a); 

	printf("向堆中插入7\n");
	heapInsert(a,7);
	printf("%d\n",*a); 

	printf("输出顶部元素\n");
	printf("%d\n",*a);

	printf("弹出顶部元素\n");
	printf("%d\n",heapExtractMax(a));

	printf("输出顶部元素\n");
	printf("%d\n",*a);
	
	return 0;
}

运行结果


zzw@zzw-ThinkPad-Edge-E430c:~/Algorithms/chap6/demo1$ ./priorityQueue 
增加第一个元素的值为6
6
向堆中插入7
7
输出顶部元素
7
弹出顶部元素
7
输出顶部元素
6



转载于:https://my.oschina.net/zzw922cn/blog/489349

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值