zoukankan      html  css  js  c++  java
  • 堆及其操作

    堆及其操作

    • 最大堆的创建
    • 最大堆的插入操作
    • 最大堆的删除操作
    • 建立最大堆

    相关的代码如下:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    #define MAXDATA 1000  //该值根据具体情况定义为大于堆中所有可能元素的值
    #define ERROR -1 //错误标志 应根据具体情况定义为堆中不可能出现的元素值
    
    //堆的C语言描述
    struct HNode
    {
    	int* Data;  //存储元素的数组
    	int Size;  //堆中当前元素的个数
    	int Capacity;  //堆的最大容量
    };
    
    struct HNode* CreatHeap(int MaxSize)
    {
    	struct HNode* H = (struct HNode*)malloc(sizeof(struct HNode));
    	H->Data = (int *)malloc((MaxSize + 1) * sizeof(int));
    	H->Size = 0;
    	H->Capacity = MaxSize;
    	H->Data[0] = MAXDATA;  //定义哨兵为大于堆中所有可能元素的值
    	return H;
    }
    //作用:判断当前堆是否为空
    bool IsFull(struct HNode* H)
    {
    	return (H->Capacity == H->Size);
    }
    
    //作用:最大堆的插入操作
    //      将元素X插入最大堆H,其中H->Data[0]已经定义为哨兵
    bool Insert(struct HNode* H,int x)
    {
    	int i;
    	if (IsFull(H))
    	{
    		printf("堆已满.
    ");
    		return false;
    	}
    
    	i = ++H->Size;  //i指向插入后堆中最后一个元素的位置
    	for ( ; H->Data[i/2] < x ; i = i / 2)
    	{
    		H->Data[i] = H->Data[i / 2];
    	}
    	H->Data[i] = x;
    	return true;
    }
    
    //判断当前堆中元素是否为空
    bool IsEmpty(struct HNode* H)
    {
    	return (H->Size == 0);
    }
    
    //作用:从最大堆中取出键值最大的元素,并删除一个节点
    int DeleteMax(struct HNode* H)
    {
    	int Parent, Child;
    	int MaxItem;
    	int X;
    	if (IsEmpty(H))
    	{
    		printf("当前堆为空.
    ");
    		return false;
    	}
    	MaxItem = H->Data[1];  //取出根节点存放的最大值
    	X = H->Data[H->Size--];  //用最大堆中最后一个元素从根节点开始向上过滤下层节点
    	                         //注意当前堆的规模要减小
    
    	for (Parent = 1;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
    		{
    			H->Data[Parent] = H->Data[Child];
    		}
    	}
    	H->Data[Parent] = X;
    	return true;
    }
    //作用:下滤 将H->Data[p]为根的子堆调整为最大堆
    void PercDown(struct HNode* H,int p)
    {
    	int Parent;
    	int Child;
    	int x;
    	x = H->Data[p];  //取出根节点存放的值
    	//退出循环的条件:当前的节点都被扫描了一遍
    	for (Parent = p; Parent * 2 <= H->Size; Parent = Child)  
    	{
    		Child = Parent * 2;
    		
    		if (H->Data[Child] < H->Data[Child + 1])
    		{
    			//当前指向了左右子节点较大值
    			Child = Child + 1;  
    		}
    		if (x >= H->Data[Child])
    		{
    			//找到了合适的位置
    			break;
    		}
    		else
    		{
    			//交换父节点和较大子节点的位置
    			H->Data[Parent] = H->Data[Child];
    		}
    	}
    	H->Data[Parent] = x;
    }
    
    //作用:最大堆的建立
    //这里假设所有H->Size个元素已经存在与H->Data[]中
    void BuildHeap(struct HNode* H)
    {
    	int i;
    	//从最后一个节点的父节点开始,到根节点
    	for (i = H->Size / 2;i > 0;i--)
    	{
    		PercDown(H,i);
    	}
    
    }
    void PrintHeap(struct HNode* H)
    {
    	for (int i = 1;i <= H->Size;i++)
    	{
    		printf("%d.
    ",H->Data[i]);
    	}
    }
    int main()
    {
    	struct HNode*  Heap = CreatHeap(15);
    	int a[] = {18,25,44,58,10,31};
    	for (int i = 1;i <= sizeof(a) / sizeof(a[0]);i++)
    	{
    		Heap->Data[i] = a[i - 1];
    		Heap->Size++;
    	}
    	printf("构建堆:
    ");
    	BuildHeap(Heap);
    	PrintHeap(Heap);
    	printf("删除元素后:
    ");
    	DeleteMax(Heap);
    	PrintHeap(Heap);
    	printf("插入元素后:
    ");
    	Insert(Heap,58);
    	PrintHeap(Heap);
    	system("pause");
    	return 0;
    }
    

    参考资料:
    1 https://www.jianshu.com/p/21bef3fc3030 最大堆(创建、删除、插入和堆排序)
    2 《数据结构》(第2版) 陈越主编

  • 相关阅读:
    Feature分支
    Bug分支
    分支管理策略
    解决冲突
    创建与合并分支
    分支管理
    Java并发与多线程教程(1)
    Java Thread(线程)案例详解sleep和wait的区别
    Spring在Thread中注入Bean无效的解决方式
    浅谈Java中的hashcode方法
  • 原文地址:https://www.cnblogs.com/Manual-Linux/p/11344403.html
Copyright © 2011-2022 走看看