学习笔记-堆

#include<stdio.h>

#include<stdlib.h>

typedef struct Node

{

              int*Elements;

              intSize;       //堆的长度

              intCapacity;   //堆的最大容量

}MinHeap;

//初始化一个堆

void Create(MinHeap *&H,int MaxSize)

{

              H=(MinHeap*)malloc(sizeof(MinHeap));

              H->Elements=(int*)malloc((MaxSize+1)*sizeof(int));

              H->Size=0;

              H->Elements[0]=-1;    //0号位置不放数据,随便设置一个最小的数为哨兵

}

bool IsFull(MinHeap *H)

{

              returnH->Size==H->Capacity;

}

//往堆里插入数据,其实可以直接在主程序里输入就行了

void Insert(MinHeap *&H,int data)

{

              inti;

              if(IsFull(H))

              {

                            printf("man");

                            return;

              }

              H->Size++;

              H->Elements[H->Size]=data;

}

//删除堆顶的数据(最小的一个数)先理解删除,创建一个堆和删除差不多

int Delete(MinHeap *H)

{

              intparent,child;

              if(!IsFull(H))

              {

                            printf("kong");

                            return0;

              }

              intmin=H->Elements[1];

              inttemp=H->Elements[H->Size];//找到堆的最后一个节点

              H->Size--;    //删去堆顶的元素

              //查找temp应该插入的位置

              for(parent=1;parent*2<=H->Size;parent=child)

              {

                            child=parent*2;

                            if(child!=H->Size&&H->Elements[child]>H->Elements[child+1])//找到两个孩子节点中小的一个

                                          child++;

                            if(temp<=H->Elements[child])//如果temp比该节点的孩子节点小,退出循环

                                          break;

                            else

                                          H->Elements[parent]=H->Elements[child];//否则该节点等于孩子节点(将孩子节点上移)

              }

              H->Elements[parent]=temp;//将temp插入该节点

              returnmin;

}

 

//堆是一个完全二叉树,

//从第一个有孩子的节点开始,看它是不是堆,不是的话通过删除所用的方法将它调整为堆

void CreateHeap(MinHeap *&H)

{

              intparent,child;

              inti;

              inttemp;

              for(i=H->Size;i>0;i--)

              {

                            if(2*i<=H->Size)//从倒数第一个有孩子的节点开始

                            {

                                          temp=H->Elements[i];

                                          for(parent=i;2*parent<=H->Size;parent=child)

                                          {

                                                        child=parent*2;

                                                        if(child!=H->Size&&H->Elements[child]>H->Elements[child+1])

                                                                      child++;

                                                        if(temp<=H->Elements[child])

                                                                      break;

                                                        else

                                                                      H->Elements[parent]=H->Elements[child];

                                          }

                                          H->Elements[parent]=temp;

                            }

              }

}

 

int IsMinHeap(MinHeap *H)

{

              inti;

              intflag=1;

              for(i=1;2*i<=H->Size;i++)

              {

                            if(H->Elements[i]>H->Elements[2*i]||H->Elements[i]>H->Elements[2*i+1]&&(2*i+1)<H->Size)

                                          flag=0;

              }

              returnflag;

 

}

int main()

{

              intn;

              scanf("%d",&n);

              MinHeap*H;

              Create(H,n);

              intdata,i;

              for(i=1;i<=n;i++)

              {

                            scanf("%d",&data);

                            Insert(H,data);

              }

              if(IsMinHeap(H)==false)

                            printf("No");

              else

                            printf("Yes");

              system("PAUSE");

              return 0;

}

 

 

 

             

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值