数据结构学习笔录--堆的实现

本文介绍了如何利用最大堆和最小堆实现优先队列,并详细展示了堆的数据结构定义、堆的操作函数以及堆的具体实现过程。

堆可以看作是一种优先队列,它并不遵循先入先出的规则,而是根据元素的优先级(关键字的大小)来取出元素,例如2,4,6,1四个元素,数值代表优先级,则针对最大堆来讲,每次取出的元素都是数字最大的那个,即取出的顺序6,4,2,1,最小堆也是类似。在操作系统进行任务调度的时候,可以使用这种优先队列--堆来实现,保证每次运行的都是任务优先级最高的。一般来讲,堆可使用完全二叉树结构存储,下面是最大堆和最小堆的实现。

1、最大堆

(1)、抽象数据类型定义

typedef int ElemType;
typedef enum{
	false,
	true
}bool;
struct Heap{
	ElemType *arry;
	int currentPos;
	int capacity;
};
typedef struct Heap MaxHeap;

(2)堆的操作

MaxHeap* createHeap(int maxsize); //创建一个空最大堆 
bool isFull(MaxHeap *MH);  //判断最大堆是否满 
bool isEmpty(MaxHeap *MH);  // 断最大堆是否空 
MaxHeap* Insert(MaxHeap *MH,ElemType e);  //向最大堆插入元素 
int Delete(MaxHeap *MH); //删除最大堆元素 
MaxHeap* creatMaxHeap(int *p_arry,int n);  //根据数据构建一个最大堆 

(3)实现

MaxHeap* createHeap(int maxsize)
{
	MaxHeap *h=(MaxHeap*)malloc(sizeof(MaxHeap));
	h->arry=(ElemType*)malloc((maxsize+1)*sizeof(ElemType));
	h->arry[0]=MaxData;
	h->capacity=maxsize;
	h->currentPos=0;
	return h;
}

bool isFull(MaxHeap *MH)
{
	if(MH->currentPos==MH->capacity)
	return true;
	else
	return false;
}
bool isEmpty(MaxHeap *MH)
{
	if(MH->currentPos==0)
	return true;
	else
	return false;
}
MaxHeap* Insert(MaxHeap *MH,ElemType e)
{
	if(isFull(MH))
	{
		printf("堆已满\n");
		return NULL;
	}
	MH->arry[++MH->currentPos]=e;
	int pos=MH->currentPos;
	for(;;pos=pos>>1)
	{
		if(MH->arry[pos]>MH->arry[pos>>1])
		{
			int temp=MH->arry[pos>>1];
			MH->arry[pos>>1]=MH->arry[pos];
			MH->arry[pos]=temp;	
		}
		else break;
	}
	return MH;
}
int Delete(MaxHeap *MH)
{
	if(isEmpty(MH))
	{
		printf("堆已空\n");
		return -1;
	}
	MH->arry[1]=MH->arry[MH->currentPos--];
	int parent=1;
	int child=1;
	for(parent=1;child<MH->currentPos;parent=child)
	{
		child=parent*2;	
		if(MH->arry[parent]<MH->arry[child])
		{
			if(child+1<=MH->currentPos && MH->arry[child+1]>MH->arry[child])
			{
				//跟右孩子交换 
				int temp=MH->arry[parent];
				MH->arry[parent]=MH->arry[child+1];
				MH->arry[child+1]=temp;	
			}
			else
			{
				//跟左孩子交换
				int temp=MH->arry[parent];
				MH->arry[parent]=MH->arry[child];
				MH->arry[child]=temp;	
			}
		}
		else if(child+1<=MH->currentPos && MH->arry[parent]<MH->arry[child+1])
		{
			//跟右孩子交换
			int temp=MH->arry[parent];
			MH->arry[parent]=MH->arry[child+1];
			MH->arry[child+1]=temp;	 
		}
		if(child==MH->currentPos||child+1==MH->currentPos)break;	
	}
	return 1;
}

MaxHeap* creatMaxHeap(int *p_arry,int n)
{
	int i;
	MaxHeap *MH=createHeap(n);
	for(i=1;i<n+1;i++)
	{
		MH->arry[i]=p_arry[i-1];
	}
	MH->currentPos=n;
	for(i=n;i>1;i--)
	{
		if(MH->arry[i>>1]<MH->arry[i])
		{
			//父子交换 
			int temp=MH->arry[i>>1];
			MH->arry[i>>1]=MH->arry[i];
			MH->arry[i]=temp;
		}
	}
	return MH; 
}
int main()
{
	int i;
	
	MaxHeap *MH=createHeap(10);
	MH=Insert(MH,2);
	MH=Insert(MH,3);
	MH=Insert(MH,4);
	MH=Insert(MH,5);
	MH=Insert(MH,6);
	MH=Insert(MH,8);
	MH=Insert(MH,10);
	
	if(MH!=NULL)
	{	
		printf("elem in list:\n");	
		for(i=1;i<MH->currentPos+1;i++)
		printf("arry[%d]=%d\n",i,MH->arry[i]);
		int re,count=0;
		while(Delete(MH)!=-1)
		{	
			count++;
			printf("after %dth delete:\n",count);
			for(i=1;i<MH->currentPos+1;i++)
				printf("arry[%d]=%d\n",i,MH->arry[i]);
		}
	}
	
	return 0;
}

2、最小堆

(1)抽象数据类型定义

typedef int ElemType;
typedef enum{
	false,
	true
}bool;
struct Heap{
	ElemType *arry;
	int currentPos;
	int capacity;
};
typedef struct Heap MinHeap;

(2)堆的操作

MinHeap* createHeap(int maxsize); //创建一个空最小堆 
bool isFull(MinHeap *MH);  //判断最小堆是否满 
bool isEmpty(MinHeap *MH);  // 断最小堆是否空 
MinHeap* Insert(MinHeap *MH,ElemType e);  //向最小堆插入元素 
int Delete(MinHeap *MH); //删除最小堆元素 
MinHeap* creatMinHeap(int *p_arry,int n);  //根据数据构建一个最小堆 

(3)最小堆实现

inHeap* createHeap(int maxsize)
{
	MinHeap *h=(MinHeap*)malloc(sizeof(MinHeap));
	h->arry=(ElemType*)malloc((maxsize+1)*sizeof(ElemType));
	h->arry[0]=MaxData;
	h->capacity=maxsize;
	h->currentPos=0;
	return h;
}

bool isFull(MinHeap *MH)
{
	if(MH->currentPos==MH->capacity)
	return true;
	else
	return false;
}
bool isEmpty(MinHeap *MH)
{
	if(MH->currentPos==0)
	return true;
	else
	return false;
}
MinHeap* Insert(MinHeap *MH,ElemType e)
{
	if(isFull(MH))
	{
		printf("堆已满\n");
		return NULL;
	}
	MH->arry[++MH->currentPos]=e;
	int pos=MH->currentPos;
	for(;;pos=pos>>1)
	{
		if(MH->arry[pos]<MH->arry[pos>>1])
		{
			int temp=MH->arry[pos>>1];
			MH->arry[pos>>1]=MH->arry[pos];
			MH->arry[pos]=temp;	
		}
		else break;
	}
	return MH;
}
int Delete(MinHeap *MH)
{
	int Parent,Child;
	if(isEmpty(MH))
	{
		printf("堆已空\n");
		return -1;
	}
	MH->arry[1]=MH->arry[MH->currentPos--];	
	int child;
	for(child=1;MH->currentPos!=0;child++)
	{	
		if(child*2<=MH->currentPos&&MH->arry[child]>MH->arry[child*2])
		{
			//父与左孩子交换
			ElemType temp=MH->arry[child];
			MH->arry[child]=MH->arry[child*2];
			MH->arry[child*2]=temp;		
		}
		if(child*2+1<=MH->currentPos&&MH->arry[child]>MH->arry[child*2+1])
		{
			//父与右孩子交换
			ElemType temp=MH->arry[child];
			MH->arry[child]=MH->arry[child*2+1];
			MH->arry[child*2+1]=temp;	
		}
		if(child*2==MH->currentPos ||child*2+1==MH->currentPos ||MH->currentPos==1)break;
	}
	return 1;
	
}
MinHeap* creatMinHeap(int *p_arry,int n)
{
	int i;
	MinHeap *MH=createHeap(n);
	for(i=1;i<n+1;i++)
	{
		MH=Insert(MH,p_arry[i-1]);
	}
	if(MH==NULL)return NULL;
	else return MH;
}
int main()
{
	int i;
	
	MinHeap *MH;
	/*=createHeap(10);
	MH=Insert(MH,6);
	MH=Insert(MH,5);
	MH=Insert(MH,3);
	MH=Insert(MH,2);
	MH=Insert(MH,12);
	MH=Insert(MH,8);
	MH=Insert(MH,5);
	MH=Insert(MH,1);
	MH=Insert(MH,10);
	MH=Insert(MH,-1);
	*/
	int a[4]={2,3,5,6}; 
	MH=creatMinHeap(a,4);
	if(MH!=NULL)
	{	
		printf("elem in list:\n");	
		for(i=1;i<MH->currentPos+1;i++)
		printf("arry[%d]=%d\n",i,MH->arry[i]);
		int re,count=0;
		while(Delete(MH)!=-1)
		{	
			count++;
			printf("after %dth delete:\n",count);
			for(i=1;i<MH->currentPos+1;i++)
				printf("arry[%d]=%d\n",i,MH->arry[i]);
		}
	}	
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值