博客
关于我
第六章第一节(二叉堆)
阅读量:260 次
发布时间:2019-03-01

本文共 2921 字,大约阅读时间需要 9 分钟。

二叉堆

堆有两个性质:结构性和堆序行,必须满足这两个性质
结构性质:堆是一棵完全填满的二叉树。完全二叉树很有规律,可以用一个数组来实现,不需要用指针
1.对数组中任一位置i上的元素,其左儿子在2i,其右儿子在2i+1的位置,它的父亲在i/2上
堆序性质:使操作被快速执行的性质使堆序性。
1.对于最小堆(最小的关键字在根上),在一个堆中,对于每一个节点X,X的父亲的关键字应小于等于X的关建字,根节点除外
2.对于最大堆(最大的关键字在根上),在一个堆中,对于每一个节点X,X的父亲的关键字应大于等于X的关键字,根节点除外

堆的基本操作(最小堆)

1.findMin(),找到最小元,只需要常数时间,最小元总是在根上
2.insert(),插入一个数到堆中
插入过程:在下一个位置创建一个空穴,插入到该位置,若不改变堆性质,则插入成功,否则,与父亲节点交换,直到满足堆的性质
这种策略叫做上滤。新元素在堆中直到找到正确的位置
3.deleteMin(),删除最小元
删除过程:把堆中的最后一个元素X,放入根节点,若不满足堆的性质,从它的子节点中找到最小的节点,交换位置,直到满足堆的性质
这种策略叫做下滤。

堆结构和声明的函数

#define MinDate -9999struct HeapStruct;typedef struct HeapStruct *PriorityQueue;struct HeapStruct {   	int Capacity;		//堆的容量大小	int Size;			//当前堆中数据的个数	int *Elements;		//存放元素};//函数声明PriorityQueue Initialize(int MaxElements);	//初始化堆void Destroy(PriorityQueue H);				//销毁堆void MakeEmpty(PriorityQueue H);			//清空堆void Insert(int X, PriorityQueue H);		//插入数据到堆int DeleteMin(PriorityQueue H);				//删除最小堆中根节点int FindMin(PriorityQueue H);				//找到最小的数据int IsEmpty(PriorityQueue H);				//判断是否为空int IsFull(PriorityQueue H);				//判断是否满

初始化函数

PriorityQueue Initialize(int MaxElements){   			//初始化堆	PriorityQueue H;	if (MaxElements < 10) {   		printf("堆太小了\n");		return NULL;	}	H = (struct HeapStruct*)malloc(sizeof(struct HeapStruct));	if (H == NULL) {   		printf("初始化失败\n");		return NULL;	}	H->Elements = (int*)malloc(sizeof(int)*(MaxElements + 1));	if (H->Elements == NULL) {   		printf("初始化失败\n");	}	H->Capacity = MaxElements;	H->Size = 0;	H->Elements[0] = MinDate;		//将第一个节点设为最小值,作为一个哨兵节点	return H;}

销毁堆函数和重置堆函数

void Destroy(PriorityQueue H) {   		//销毁堆,释放申请的空间	if (H !=  NULL) {   		if (H->Elements != NULL) {   			free(H->Elements);		}		free(H);	}}void MakeEmpty(PriorityQueue H) {   		//清空堆中的数据	if (H!=NULL) {   		H->Size = 0;	}}

判断堆空和堆满的函数,返回最小值的函数

int IsEmpty(PriorityQueue H) {   		//判断是否为空	if (H->Size == 0) {   		return 1;	}	return 0;}int IsFull(PriorityQueue H) {   		//判断是否已满	if (H->Size == H->Capacity) {   		return 1;	}	return 0;}int FindMin(PriorityQueue H) {   			//找到最小的数据	return H->Elements[1];}

插入数据函数

void Insert(int X,PriorityQueue H) {   		//插入数据	int i;	if (IsFull(H)) {   		printf("堆中元素已满\n");		return;	}	for (i = ++H->Size; H->Elements[i / 2] > X; i /= 2) {   		//循环进行上滤操作		H->Elements[i] = H->Elements[i / 2];	}	H->Elements[i] = X;	//找到位置,成功插入}

弹出最小值并调整堆结构函数

int DeleteMin(PriorityQueue H) {   		//弹出最小的元素,调整最小堆	int i, child;	int MinElement, LastElement;		if (IsEmpty(H)) {   		printf("堆为空\n");		return H->Elements[0];	}	MinElement = H->Elements[1];	LastElement = H->Elements[H->Size--];	for (i = 1; i * 2 <= H->Size;i = child) {   		//寻找最小的孩子		child = i * 2;		if (child !=H->Size &&H->Elements[child] > H->Elements[child + 1]) {   			child++;		}		//判断,如果最小的孩子比最后位置的数小,那么删除空的位置由子节点代替,空格下滤		if (LastElement > H->Elements[child]) {   			H->Elements[i] = H->Elements[child];		}		//若最小的孩子比最后位置的数大,删除空的位置由最后位置的数代替,下滤完成,跳出循环		else {   			break;		}	}	H->Elements[i] = LastElement;	return MinElement;}

转载地址:http://jmyo.baihongyu.com/

你可能感兴趣的文章
实用软件推荐(一)——自动更换壁纸 (Dynamic theme)
查看>>
从零开始免费搭建自己的博客(七)——迁移 CSDN 博客到个人博客站点
查看>>
RF新手常见问题总结--(基础篇)
查看>>
spring框架读取json文件为字符串 推荐第一种
查看>>
SpringBoot配置文件中的值获取
查看>>
Java实现压缩与解压
查看>>
Mybatis-plus代码生成器模板(MySQL数据库)
查看>>
使用redis管理Mybatis的二级缓存
查看>>
购物车的实现及使用redis存储购物车数据
查看>>
使用redis管理Mybatis-Plus的二级缓存
查看>>
Spring Boot常用的maven依赖
查看>>
Mybatis中的SQL语句等于、不等于和模糊查询的语法
查看>>
用xacro给自己的ROS小车编写模型
查看>>
使用 github 搜索
查看>>
.net core 中使用 EFcore做ORM
查看>>
那些用过一次就不会卸载的软件
查看>>
工具-snipate(截图)
查看>>
java有包名的类访问没有包名的类
查看>>
python中快速删除重复元素
查看>>
修改 pytorch中的model zoo下载后的模型的保存目录
查看>>