堆的c语言实现

堆的特性:

1.结构性:是一个完全二叉树(所以可以用数组储存)

2.有序性:任意结点的关键字都是其子树所有结点的最大值

用数组的方式来表示最大堆

typedef int ElementType;
#define MaxDate 100000;
typedef struct HeapStruct{
    ElementType *Elements;
    int Size;//当前元素个数
    int Capacity;//堆的容量
}*MaxHeap;

最大堆的操作:

创建一个最大堆

MaxHeap Create(int MaxSize)
{
    MaxHeap H=(MaxHeap)malloc(sizeof(HeapStruct));
    H->Elements=(ElementType *)malloc(sizeof(ElementType)*(MaxSize+1));
    H->Size=0;
    H->Capacity=MaxSize;
    H->Elements[0]=MaxDate;//哨兵
    return H;
}

最大堆的插入

算法:将新增结点插入到其父节点到根结点的这条路径上

void Insert(MaxHeap H,ElementType Item)
{
    int i=++H->Size;
    for(;H->Elements[i/2]<Item;i/=2)//i向上移
    {
        H->Elements[i]=H->Elements[i/2];//父节点向下移
    }
    H->Elements[i]=Item;
}

最大堆的删除

算法:将最后一个结点替换到根结点的位置,然后与其左右儿子中较大的比较,如果父节点小,则将儿子结点向上移

父节点向下移。否则找到正确的位置。时间复杂度为logn。

ElementType Delete(MaxHeap H)
{
    int parent,child;
    ElementType MaxItem,term;
    MaxItem = H->Elements[1];
    term=H->Elements[H->Size--];
    for(parent=1;2*parent<=H->Size;parent=child)//parent指示要移动到的位置,位置向下移
    {
        child = 2*parent;
        if(child+1<=H->Size&&H->Elements[child]<H->Elements[child+1])
            child++;//child指示左右儿子中较大的那个
        if(term>=H->Elements[child])
            break;
        else
        {
            H->Elements[parent]=H->Elements[child];//儿子向上移
        }
    }
    H->Elements[parent]=term;
    return MaxItem;
}

最大堆的建立

算法1:将给定元素一个一个插入到最大堆中,每个元素插入的时间复杂度为O(logn),一共n个元素,总体时间复杂度为O(nlog(n))

算法2:将给定元素依次进入堆中,满足最大堆结构特性。再从最后一个父节点开始调整(调整策略同删除操作,即向下过滤)。时间复杂度为O(n)

MaxHeap BuildMaxHeap( MaxHeap H )
{   /* 这里假设所有H->Size个元素已经存在H->Elements[]中     */
    /* 本函数将H->Elements[]中的元素调整,使满足最大堆的有序性 */
	int Parent, Child, i;
	ElementType temp;

	for( i = H->Size/2; i>0; i-- )
    { /*从最后一个结点的父结点开始调整 */
		temp = H->Elements[i];
		for( Parent=i; Parent*2<=H->Size; Parent=Child ) { /* 向下过滤 */
			Child = Parent * 2;
            if( (Child!= H->Size) && (H->Elements[Child] < H->Elements[Child+1]) )
                Child++;  /* Child指向左右子结点的较大者 */
            if( temp >= H->Elements[Child] ) break;
			else  /* 移动temp元素到下一层 */
				H->Elements[Parent] = H->Elements[Child];
		} /* 结束内部for循环对以H->Elements[i]为根的子树的调整 */
		H->Elements[Parent] = temp;
	}

	return H;
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值