斜堆:是左式堆的自调节形式。是具有堆序的二叉树,但是不存在对树的结构限制,所以数据结构中***没有存储零路径长度的数据***。
与左式堆一样,斜堆的基本操作也是合并,但是与左式堆不同,在左式堆中,
如果节点的右儿子的零路径长度大于左儿子的零路径长度,则进行交换,在斜堆合并时,不做判断,左右儿子直接进行交换。
代码
#include<stdio.h>
#include<stdlib.h>
//数据结构
struct TreeNode;
typedef struct TreeNode *PriorityQueue;
//节点的数据结构
struct TreeNode {
int Element; //属性值
PriorityQueue Left; //左指针
PriorityQueue Right; //右指针
};
//函数声明
PriorityQueue Initialize();
int FindMin(PriorityQueue H);
int IsEmpty(PriorityQueue H);
#define Insert(X,H) (H = Insert1((X),H))
#define DeleteMin(H) (H = DeleteMin1(H))
PriorityQueue Insert1(int X, PriorityQueue H);
PriorityQueue DeleteMin1(PriorityQueue H);
PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2);
static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2);
PriorityQueue Initialize(void) { //左式堆初始化
return NULL;
}
int IsEmpty(PriorityQueue H) { //判断堆是否为空
if (H == NULL) {
return 1;
}
return 0;
}
int FindMin(PriorityQueue H) { //找到最小的值,即树根位置
if (!IsEmpty(H)) {
return H->Element;
}
return NULL;
}
PriorityQueue Insert1(int X, PriorityQueue H) {
//插入斜堆
PriorityQueue NewHeap = (PriorityQueue)malloc(sizeof(struct TreeNode));
NewHeap->Element = X;
NewHeap->Left = NULL;
NewHeap->Right = NULL;
H = Merge(H, NewHeap);
return H;
}
PriorityQueue DeleteMin1(PriorityQueue H) {
//删除函数,将根节点删除,将左右子树合并
if (IsEmpty(H)) {
printf("堆为空\n");
return NULL;
}
PriorityQueue LeftHeap, RightHeap;
LeftHeap = H->Left;
RightHeap = H->Right;
free(H);
LeftHeap = Merge(LeftHeap, RightHeap);
return LeftHeap;
}
PriorityQueue Merge(PriorityQueue H1, PriorityQueue H2) {
//若一个堆为空,则返回另一个堆,俩个都不为空,则将根节点大的堆与根节点小的堆合并
if (IsEmpty(H1)) {
return H2;
}
if (IsEmpty(H2)) {
return H1;
}
if (H1->Element > H2->Element) {
Merge1(H2, H1);
}
Merge1(H1, H2);
}
static PriorityQueue Merge1(PriorityQueue H1, PriorityQueue H2) {
if (H1->Left == NULL) {
H1->Left = H2;
}
else {
H1->Right = Merge(H1->Right, H2);
//合并后,直接交换左右节点
PriorityQueue T;
T = H1->Left;
H1->Left = H1->Right;
H1->Right = T;
}
return H1;
}