堆——堆的操作集、建造堆及打印堆中的路径

1 堆的类型定义

typedef struct HeapStruct *Heap  /*堆的类型定义*/
struct HeapStruct {
             ElementType *Data; /*存储元素的数组*/
             int Size;                /*堆的当前元素个数*/
             int Capacity;          /*堆的最大容量*/
};
typedef Heap MaxHeap;  /*最大堆*/
typedef Heap MinHeap;  /*最小堆*/

2 创建容量为MaxSize的空的最大堆

#define MaxData 10000  /* 该值应根据具体情况定义为大于堆中所有可能元素的值 */

MaxHeap CreateHeap( int MaxSize){
MaxHeap H = (Maxheap)malloc(sizeof(struct HeapStruct));
H->Data = (ElementType *)malloc((MaxSize+1)*sizeof(ElementType));
H->Size = 0;
H->Capacity = MaxSize;
H->Data[0] = MaxData;  /* 定义"哨兵"为大于堆中所有可能元素的值*/

return H;
}

3 最大堆的插入(T(N) = O(logN))

bool IsFull( MaxHeap H){ 
return (H->Size == H->Capacity);
}

bool Insert(MaxHeap H , ElementType X){
/* 将元素X插入最大堆H,其中H->Data[0]已经定义为哨兵 */
int i; /*i为要插入的数组位置下表*/

if(IsFull(H)){
printf("最大堆已满");
return false;
}
i = ++H->Size; /* i指向插入后堆中的最后一个元素的位置 */
for(;H->Data[i/2]Data[i] = H->Data[i/2];  /* 上滤X */
H->Data[i] = item; /* 将X插入 */
return true;
}

4 最大堆的删除(T(N) = O(logN))

#define ERROR  -1; /* 错误标识应根据具体情况定义为堆中不可能出现的元素值 */

bool IsEmpty(MaxHeap H){
return(H->Size ==0);
}

ElementType DeleteMax( MaxHeap H){
ElemetType MaxItem,Temp;
int Parent, Child; 
MaxItem = H->Data[1];
Temp = H->Data[H->Size--];
for(Parent = 1;H->Size >= 2*Parent;){ /*从根节点开始向上过滤下层结点,主要目的是要找Temp要插入的位置Parent*/
Child = 2*Parent; /*先默认为左儿子,因为根据前面判断条件它可能没有右儿子*/
if((H->Size > Child) && 
(H->Data[Child]Data[Child+1]))/*如果有右儿子并且右儿子比左儿子大*/
Child++;
 if(H->Data[Child]>Temp) {  /*注意这里是和Temp比较,不是H->Data[Parent]*/
H->Data[Parent] = H->Data[Child];

Parent = Child; /*可以放到for语句里*/
}
 else break;
}
H->Data[Parent] = Temp ;
return MaxItem ;
}

5 最大堆的建立(T(N) = O(N))

两种方法:

  1. 方法1:通过插入操作,将N个元素一个个相继插入到一个初始为空的堆中去,时间复杂度为O(NlogN)
  2. 方法2:在线性时间复杂度上建立堆。O(N)
    (1)将N个元素按输入顺序存入,先满足完全二叉树的结构特性。
    (2)调整各结点位置,以满足最大堆的有序特性。
void BuildHeap( MaxHeap H )
{/* 这里假设传入的最大堆是个数是空的 */
  int i;
  for(i=1;i<=N;i++){/* 这里假设元素个数N不大于MaxSize*/
scanf("%d",&H->Data[i]);
H->Size++;

return H;
}

 /* 调整H->Data[]中的元素,使满足最大堆的有序性  */
    /* 从最后一个结点的父节点开始,到根结点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]Data[Child+1]) )
            Child++;  /* Child指向左右子结点的较大者 */
        if( X >= H->Data[Child] ) break; /* 找到了合适位置 */
        else  /* 下滤X */
            H->Data[Parent] = H->Data[Child];
    }
    H->Data[Parent] = X;
}

6 打印堆中的路径

堆——堆的操作集、建造堆及打印堆中的路径_第1张图片


#include
#include
#define bool char
#define ture 1
#define false 0
#define MinData -10001
#define MaxSize 10001
typedef int ElementType;
typedef struct HeapStruct *MinHeap;/*堆的类型定义*/
struct HeapStruct {
             ElementType *Data; /*存储元素的数组*/
             int Size;                /*堆的当前元素个数*/
             int Capacity;          /*堆的最大容量*/
};

MinHeap CreateHeap( int Size){
MinHeap H = (MinHeap)malloc(sizeof(struct HeapStruct));
H->Data = (ElementType *)malloc((Size+1)*sizeof(ElementType ));
H->Size = 0;
H->Capacity = MaxSize;
H->Data[0] = MinData ;  /* 定义"哨兵"为小于堆中所有可能元素的值*/
return H;
}

bool IsFull( MinHeap H){ 
return (H->Size == H->Capacity);
}

bool Insert(MinHeap H,ElementType X){
/* 将元素X插入最大堆H,其中H->Data[0]已经定义为哨兵 */
int i; /*i为要插入的数组位置下表*/

if(IsFull(H)){
printf("最大堆已满");
return false;
}
i = ++H->Size; /* i指向插入后堆中的最后一个元素的位置 */
for(;H->Data[i/2]>X;i/=2)
H->Data[i] = H->Data[i/2];  /* 上滤X */
H->Data[i] = X; /* 将X插入 */
return ture;
}
int main(){
  int n,m,x,i,j;
  scanf("%d%d",&n,&m);
  MinHeap H = CreateHeap(MaxSize );      /*堆初始化*/
				for(i=0;i=1;j/=2){
			            printf("%d",H->Data[j]);
			        }
			 printf("\n");       
			 }
return 0;
}

你可能感兴趣的:(数据结构,堆)