左式堆

数据结构与算法分析——c语言描述 第六章


代码不难。反倒是理解merge挺难的。

一个左式堆,它的子树也是左式堆。合并就是不断递归,直到找到一个空指针,然后合并。并且判断左边的npl是不是大于等于右边的npl。在一层一层返回。所以合并的又是一个左式堆。


leftheap.h

#ifndef _LeftHeap_H
#define _LeftHeap_H
typedef int ElementType;

struct TreeNode;
typedef struct TreeNode *PriorityQueue;

PriorityQueue initialize(void);
ElementType findMin(PriorityQueue h);
int isEmpty(PriorityQueue h);
PriorityQueue merge(PriorityQueue h1, PriorityQueue h2);
#define insert(X,H) (H=insert1((X),H))
PriorityQueue insert1(ElementType X, PriorityQueue h);
PriorityQueue deleteMin1(PriorityQueue h);
#define deleteMin(H) (H=deleteMin1(H))

#endif // !_BinHeap_H


leftheap.c

#include"leftheap.h"
#include"fatal.h"

struct TreeNode {
	ElementType element;
	PriorityQueue left;
	PriorityQueue right;
	int np1;
};

PriorityQueue initialize(void) {
	return NULL;
}

ElementType findMin(PriorityQueue h) {
	if (isEmpty(h))
		Error("EMPTY HEAP");
	return h->element;
}

int isEmpty(PriorityQueue h) {
	return h == NULL;
}


static PriorityQueue merge1(PriorityQueue h1, PriorityQueue h2) {
	if (h1->left == NULL) {
		h1->left = h2;
		return h1;
	}
	else {
		h1->right= merge(h1->right, h2);
		if (h1->right->np1 > h1->left->np1) {
			PriorityQueue temp;
			temp = h1->right;
			h1->right = h1->left;
			h1->left = temp;
		}
		h1->np1 = h1->right->np1 + 1;
		return h1;
	}
}

PriorityQueue merge(PriorityQueue h1, PriorityQueue h2) {
	if (h1 == NULL)
		return h2;
	else if (h2 == NULL)
		return h1;
	else {
		if (h1->element < h2->element)
			return merge1(h1, h2);
		else
			return merge1(h2, h1);
	}
}

PriorityQueue insert1(ElementType X, PriorityQueue h) {
	PriorityQueue newNode = malloc(sizeof(struct TreeNode));
	newNode->element = X;
	newNode->left = NULL;
	newNode->right = NULL;
	newNode->np1 = 0;
	return merge(newNode, h);
}

PriorityQueue deleteMin1(PriorityQueue h) {
	PriorityQueue temp1 = h->left;
	PriorityQueue temp2 = h->right;
	free(h);
	return merge(temp1, temp2);
	
}


main.c

#include"leftheap.h"
#include<stdlib.h>
#include<stdio.h>

int RandInt(int i, int j) {
	int temp;
	temp = (int)(i + (1.0*rand() / RAND_MAX)*(j - i));
	return temp;
}

void getRandomInt(int *A, int n) {
	for (int i = 0; i < n; i++) {
		A[i] = i + 1;
	}

	for (int i = 1; i < n; i++) {
		//std::swap(A[i], A[RandInt(0, i)]);  
		int randAdrr = RandInt(0, i);
		int t = A[i];
		A[i] = A[randAdrr];
		A[randAdrr] = t;
	}
}

int a[99999999];

int main() {
	int n;
	scanf("%d", &n);
	//int *a = malloc(sizeof(int)*n);
	//if (a == NULL)
	//	fprintf(stderr,"out of memory");
	getRandomInt(a, n);

	PriorityQueue h1 = initialize();
	PriorityQueue h2 = initialize();
	int i;
	for (i = 0; i < n / 2; i++)
		insert(a[i], h1);
	for (; i < n; i++)
		insert(a[i], h2);

	PriorityQueue h = merge(h1, h2);

	for (int i = 0; i < n; i++) {
		printf("%d ", findMin(h));
		deleteMin(h);
	}
	
	//destroy(h);
	//free(a);
	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值