您的位置:首页 > 理论基础 > 数据结构算法

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

2015-04-20 14:57 85 查看
堆可以看作是一种优先队列,它并不遵循先入先出的规则,而是根据元素的优先级(关键字的大小)来取出元素,例如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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: