最小堆实现最小优先队列

最小优先队列的可以实现的操作:
insert,插入一个元素
min,找到最小的元素
extract-min,去掉最小的元素并返回最小的元素
increase-key,增加一个关键字的值

优先队列的形式是一个堆。也就是有parent,left,right和自身的值的形式。实现他的操作是依赖于堆的操作,比如要插入一个key,实际上就是在堆中去找key的位置,然后维护堆。所以要时刻清醒的是现在的堆是一种什么形式,输出这个优先队列只是把堆按照数组的形式输出来了,本质上是在输出堆。


#include "stdafx.h"
#include<stdio.h>
#include <limits.h>


//最小堆实现最小优先序列

void swap(int *x, int *y)          //用作交换值的函数
{
	int t;
	t = *x;
	*x = *y;
	*y = t;

}

int parent(int i) //计算关系结点编号
{
	return i / 2;
}
int left(int i)
{
	return 2 * i;
}

int right(int i)
{
	return 2 * i + 1;
}

void minheap(int a[], int i,int truesize) //维护最xiao堆性质
{
	int smallest;  //储存最xiao结点编号
	int l;     //左结点
	int r;     //右 

	l = left(i);
	r = right(i);
	if (a[l - 1] < a[i - 1] && l <= truesize) //注意 C语言数组下标应该将i-1
		smallest = l;
	else
		smallest = i;
	if (a[r - 1] < a[smallest - 1] && r <= truesize)
		smallest = r;
	if (smallest != i)
	{
		swap(&a[smallest - 1], &a[i - 1]);               //逐层维hu        
		minheap(a, smallest,truesize);
	}
}

void buildminheap(int a[],int truesize)  //建立最xiao堆
{
	int n = truesize;
	int i;
	for (i = n / 2; i > 0; i--)
	{
		minheap(a, i,n);
	}
}

void heapsort(int a[],int truesize)  //堆排序,从大到小输出
{
	
	int i =truesize;
	for (; i>0; i--)
	{
		swap(&a[i - 1], &a[0]);
		truesize--;
		minheap(a, 1,truesize);
	}
}

int heap_min(int a[],int n)
{
	
	return a[0];
}

int heap_extract_min(int a[],int n)            
{
	

	if (n < 1)
		return 0;
	int min = a[0];
	a[0] = a[n - 1];
	n--;
	minheap(a,1,n);
	return min;

}

int  heap_increase_key(int a[], int i, int key)
{
	if (key > a[i])
	{                         //当key>parent 的时候终止
		return 0;
	}
	
	a[i] = key;
	while (i > 0 && a[parent(i)] > a[i])
	{
		swap(&a[i], &a[parent(i)]);
		i = parent(i);
	}
	
}

void min_heap_insert(int a[], int key,int n)
{
	n++;
	
	a[n - 1] = 100000;        //插入后的位置预置为正无穷
	heap_increase_key(a, n-1, key);
}




int main()
{
	int a[10] = { 4,1,3,2,16,9,10,14,8,7 };
	int  i,n=10;
	printf("\n堆中的元素是------------------\n");
	for (i = 0; i < n; i++) //输入堆中元素
		printf("%d   ", a[i]);

	printf("\n最小堆------------------\n");
	buildminheap(a,n);    //建立最xiao堆
	for (i = 0; i < n; i++)
		printf("%d ", a[i]);  //输出


/*	heapsort(a,n);       //堆排序
	printf("\nresult------------------\n");
	for (i = 0; i < n; i++)
		printf("%d ", a[i]);   //输出结果
*/

	heap_min( a,n);

    heap_extract_min(a,n);
	printf("\n调用extract后的最小堆:\n");
	for (i = 0; i < n-1; i++)
		printf("%d ", a[i]);   //输出结果
	printf("\n");


	min_heap_insert(a, 5, n-1);                //插入5
	
	printf("插入后的最小堆\n");
	for (i = 0; i < n; i++)
		printf("%d   ", a[i]);   //输出结果

	printf("\n插入后的堆排序\n");
	heapsort(a, n);
	for (i = 0; i < n; i++)
		printf("%d   ", a[i]);   //输出结果
		return 0;	
}

因为我一开始没有理解上面我所说的,队列的操作都是在操作堆,所以理解上出现了问题。在输出最小值的时候,我先用了heapsort进行堆排序然的
就觉得最小值应该是数组中的最后一个。把堆按sort输出了这样其实是没错的,但是到下面就出现问题了。extract_min一直是对一个最小堆在操作的,当你把你的最小堆sort成一个递减的数组的数组的时候,进行的操作是把堆顶元素与最后一个元素互换,然后把堆里的元素减少1,再把最后一个元素输出,最后一个元素即堆顶元素一定是当前的最小值,继续维护最小堆,重复这个过程。在这个过程中堆里的元素已经在减少了,最后堆已经没了。然后再去进行extract等一系列操作就不是在原来最小堆的基础上操作了。。。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值