博客
关于我
第六章第一节(二叉堆)
阅读量: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/

你可能感兴趣的文章
2021-01-12:多维快查多维查询系统,你了解的解决方案都有哪些?
查看>>
2021-01-17:java中,HashMap底层数据结构是什么?
查看>>
2021-01-21:java中,HashMap的读流程是什么?
查看>>
Imagination官方信息速递2021年光线追踪专刊
查看>>
计算机视觉中的双目立体视觉和体积度量
查看>>
什么是数据中心,它们是如何变化的?
查看>>
516. Longest Palindromic Subsequence
查看>>
1249. Minimum Remove to Make Valid Parentheses
查看>>
Linux系统基础
查看>>
运维相关的命令
查看>>
java第四话:数组知识点讲解
查看>>
JavaScript练习题 幸运猜猜猜
查看>>
部件构建基块、Word封面标准的秘密
查看>>
奇怪、为什么Word没有标题3以后的样式?
查看>>
Word图文混排中图片的高级处理技巧
查看>>
Python自学17(IO 操作)
查看>>
找链表中倒数第K个结点
查看>>
《算法竞赛进阶指南》0x01 T1 a^b
查看>>
开始学习深度学习啦!
查看>>
JS中的常用继承方式总结
查看>>