二叉堆的一些基本操作(未完待续)

来源:互联网 发布:收到短信淘宝内部qq群 编辑:程序博客网 时间:2024/06/04 23:35

#include "stdafx.h"#include "iostream"#include "stdlib.h"typedef int ElementType;typedef struct HNode *Heap;typedef Heap MaxHeap;struct HNode{  ElementType *Date;  int Size;  int Captity;};#define MAXDATA 1000MaxHeap CreateHeap(int MaxSize){  MaxHeap H=(MaxHeap)malloc(sizeof(struct HNode));  if(H==NULL)    { printf("error");         break;     }  H->Captity=MaxSize;  H->Size=0;  H->Date=(ElementType*)malloc(sizeof(ElementType)*(H->Captity+1));//这里加1是为了多放一个哨兵;  H->Date[0]=MaxSize;}bool IsFull(MaxHeap H){  return(H->Size==H->Captity);}bool Insert(MaxHeap H,ElementType x){  int i;  if(IsFull(H))  {     printf("FULL");     return false;   }     i=++H->Size;//因为存储的数组     for(;H->Date[i/2]<x;i/=2)      {        H->Date[i]=H->Date[i/2];//直接把大的拉下马,这不是搜索树不用管左儿子大还是右儿子大      }     H->Date[i]=x;     return true;   }bool IsEmpty(MaxHeap H){    return(H->Size==0);}ElementType DeleteMax(MaxHeap H){   if(IsEmpty(H))   {    printf("Empty");    return -1;    }    ElementType Max,x;    int parent,child;    Max=H->Date[1];//取出最大的结点    x=H->Date[H->Size--];//取出最小结点暂放最大结点并减小规模;    for(parent=1;parent*2<H->Size;parent=child)     {       child=parent*2;//获得左儿子;       if(child!=H->Size&&(H->Date[child]<H->Date[child+1]))//获得左右儿子较大者       child=child+1;       if(H->Date[child]>=x)       H->Date[parent]=H->Date[child];//小了就往下撸,因为儿子都是二叉堆,所以只比较新上来的这个就行       else       break;      }    H->Date[parent]=x;//因为每次循环结束都要把child赋给parent;}//这里的方法在下面用percDown封装好了,可以直接掉那个函数//即如果调用PercDown()函数  建立、删除如下ElementType DeleteMax(MaxHeap H){    ElementType Max=H->Date[1];    H->Date[1]=H->Date[H->Size--];    percDown(H,1);    return Max;}void BuildHeap( MaxHeap H ){ /* 调整H->Data[]中的元素,使满足最大堆的有序性  */  /* 这里假设所有H->Size个元素已经存在H->Data[]中 */     int i;     /* 从最后一个结点的父节点开始,到根结点1 */    for( i = H->Size/2; i>0; i-- )        PercDown( H, i );}/*----------- 建造最大堆 -----------*void PercDown( MaxHeap H, int p ){ /* 下滤:将H中以H->Data[p]为根的子堆调整为最大堆 */ int Parent, Child; ElementType X; X = H->Data[p]; /* 取出根结点存放的值 */ for( Parent=p; Parent*2<=H->Size; Parent=Child ) { Child = Parent * 2; if( (Child!=H->Size) && (H->Data[Child]<H->Data[Child+1]) ) Child++; /* Child指向左右子结点的较大者 */ if( X >= H->Data[Child] ) break; /* 找到了合适位置 */ else /* 下滤X */ H->Data[Parent] = H->Data[Child]; } H->Data[Parent] = X;}