最小堆的删除

#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 20
#define OK 1
#define ERROR 0

typedef int Status;
typedef int ElemType;

typedef struct 
{
    ElemType heapArray[MAXSIZE];
    int length;
}MinHeap;

//对数组进行元素的输入
Status Init_heapArray(MinHeap * M,int Number)
{
    ElemType data;
    for(int i=0;i<Number;i++)
    {
        scanf("%d",&data);
        M->heapArray[i]=data;
        M->length++;
    }
    return OK;
}



//最小堆的初始化
Status Init_MinHeap(MinHeap * M)
{
    int Number;
    M->length=0;
    printf("请输入数组的元素个数:\n");
    scanf("%d",&Number);
    printf("请输入%d个数据:\n",Number);
    Init_heapArray(M,Number);
    return OK;
}



int MinHeap_Leftchild(int pos)  //返回左孩子的下标
{
    return 2*pos+1;
}


int MinHeap_Rightchild(int pos) //返回右孩子的下标
{
    return 2*pos+2;
}


int MinHeap_Parent(int pos) //返回双亲的下标
{
    return (pos-1)/2;
}



void MinHeap_SiftDown(MinHeap * M,int left)
{
    int i=left; //标识父结点
    int j=MinHeap_Leftchild(i); //用于记录关键值较小的子结点
    ElemType temp=M->heapArray[i];  //保存父结点
    while(j<M->length)  //过筛
    {
        if((j<M->length-1)&&(M->heapArray[j]>M->heapArray[j+1]))    //若有右子结点,且小于左子结点
        {
            j++;    //j指向右子结点
        }
        if(temp>M->heapArray[j])    //如果父结点大于子结点的值则交换位置
        {
            M->heapArray[i]=M->heapArray[j];
            i=j;
            j=MinHeap_Leftchild(j);
        }
        else    //堆序性满足时则跳出
        {
            break;
        }
    }
    M->heapArray[i]=temp;
}


//建立最小堆
void Create_MinHeap(MinHeap * M)
{
    for(int i=M->length/2-1;i>=0;i--)
    {
        MinHeap_SiftDown(M,i);
    }
}



void MinHeap_SiftUp(MinHeap * M,int position)   //从position开始向上调整
{
    int temppos=position;
    ElemType temp=M->heapArray[temppos];    //记录当前元素
    while((temppos>0) && (M->heapArray[MinHeap_Parent(temppos)]>temp))  //temppos>0,结束于根结点
    {
        M->heapArray[temppos]=M->heapArray[MinHeap_Parent(temppos)];
        temppos=MinHeap_Parent(temppos);
    }
    M->heapArray[temppos]=temp;
}



Status MinHeap_Delete(MinHeap * M,int pos,ElemType * Del)
{
    if((pos<0) || (pos>=M->length))
    {
        return ERROR;
    }
    (*Del)=M->heapArray[pos];   //记录删除的元素
    M->heapArray[pos]=M->heapArray[--M->length];    //用最后的元素值替代被删除的结点
    if(M->heapArray[MinHeap_Parent(pos)]>M->heapArray[pos]) //当前元素小于父结点,需要向上调整
    {
        MinHeap_SiftUp(M,pos);
    }
    else    //当前元素大于父结点,向下筛选
    {
        MinHeap_SiftDown(M,pos);
    }
    return OK;
}



//输出元素
void Print(MinHeap * M)
{
    for(int i=0;i<M->length;i++)
    {
        printf("%d ",M->heapArray[i]);
    }
    printf("\n");
}


int main()
{
    MinHeap M;
    ElemType Del;
    int Del_pos;
    Init_MinHeap(&M);
    printf("输出先前元素:\n");
    Print(&M);
    Create_MinHeap(&M);
    printf("输出最小堆的元素:\n");
    Print(&M);
    printf("请输入删除元素的下标:\n");
    scanf("%d",&Del_pos);
    MinHeap_Delete(&M,Del_pos,&Del);
    printf("删除的元素为:%d\n",Del);
    printf("输出删除后的元素:\n");
    Print(&M);  
    return 0;
}

这里写图片描述
这里写图片描述
这里写图片描述

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值