《数据结构与算法分析——c语言描述》 练习6.21 答案
leftheap.h
#ifndef _LeftHeap_H
#define _LeftHeap_H
typedef int ElementType;
struct TreeNode;
typedef struct TreeNode *PriorityQueue;
PriorityQueue initialize(void);
ElementType findMin(PriorityQueue &h);
void destroy(PriorityQueue h);
int isEmpty(PriorityQueue h);
PriorityQueue merge(PriorityQueue h1, PriorityQueue h2);
PriorityQueue insert(ElementType X, PriorityQueue h);
PriorityQueue deleteMin(PriorityQueue h);
void Delete(ElementType X, PriorityQueue h);
#endif // !_BinHeap_H
leftheap.cpp
#include"leftheap.h"
#include"fatal.h"
#include<queue>
struct TreeNode {
ElementType element;
PriorityQueue left;
PriorityQueue right;
int np1;
int isDeleted;
};
static void preorderTraversal(PriorityQueue h, std::queue<PriorityQueue> & q) {
if (h->isDeleted == 1) {
if (h->left && h->left->isDeleted == 0)
q.push(h->left);
if (h->right &&h->right->isDeleted == 0)
q.push(h->right);
}
else {
preorderTraversal(h->left, q);
preorderTraversal(h->right, q);
}
}
static PriorityQueue clearLazyDelete(PriorityQueue h) {
std::queue<PriorityQueue> q;
preorderTraversal(h, q);
while (q.size() > 1) {
PriorityQueue h1 = q.front();
q.pop();
PriorityQueue h2 = q.front();
q.pop();
q.push(merge(h1, h2));
}
return q.front();
}
PriorityQueue initialize(void) {
return NULL;
}
ElementType findMin(PriorityQueue &h) {
if (isEmpty(h))
Error("EMPTY HEAP");
if (h->isDeleted == 1)
h=clearLazyDelete(h);
return h->element;
}
void destroy(PriorityQueue h) {
if (h) {
destroy(h->left);
destroy(h->right);
free(h);
}
}
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 insert(ElementType X, PriorityQueue h) {
PriorityQueue newNode = (PriorityQueue)malloc(sizeof(struct TreeNode));
newNode->element = X;
newNode->left = NULL;
newNode->right = NULL;
newNode->np1 = 0;
newNode->isDeleted = 0;
return merge(newNode, h);
}
PriorityQueue deleteMin(PriorityQueue h) {
if (h->isDeleted == 1) {
h= clearLazyDelete(h);
}
PriorityQueue temp1 = h->left;
PriorityQueue temp2 = h->right;
free(h);
return merge(temp1, temp2);
}
static void swapLeftRightSon(PriorityQueue h) {
PriorityQueue temp;
temp = h->right;
h->right = h->left;
h->left = temp;
}
/*
static PriorityQueue deleteKey_real2(ElementType X, int *isFind, PriorityQueue h) {
if (h) {
if (X > h->element) {
h->left = deleteKey_real2(X, isFind, h->left);
if (*isFind == 0) {//没有找到
h->right = deleteKey_real2(X, isFind, h->right);
}
if (h->left == NULL) {
h->left = h->right;
h->right = NULL;
h->np1 = 0;
}
else if (h->right == NULL) {
h->np1 = 0;
}
else {
if (h->right->np1 > h->left->np1)
swapLeftRightSon(h);
h->np1 = h->right->np1 + 1;
}
}
else if (X == h->element) {
PriorityQueue newMergeRoot = merge(h->left, h->right);
free(h);
*isFind = 1;
h = newMergeRoot;
}
}
return h;
}
static PriorityQueue deleteKey_real(ElementType X, PriorityQueue h) {
int isFind = 0;
return deleteKey_real2(X, &isFind, h);
}
*/
static PriorityQueue find_internal(ElementType X, PriorityQueue h) {
if (h) {
PriorityQueue ret;
if (X > h->element) {
if (ret = find_internal(X, h->left))
return ret;
else if (ret = find_internal(X, h->right))
return ret;
}
else if (X == h->element) {
return h;
}
}
return NULL;
}
void Delete(ElementType X, PriorityQueue h) {
PriorityQueue pnode = find_internal(X, h);
if (pnode)
pnode->isDeleted = 1;
}
main.cpp
#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];
struct TreeNode {
ElementType element;
PriorityQueue left;
PriorityQueue right;
int np1;
int isDeleted;
};
void dir(PriorityQueue h, int depth) {
if (h) {
for (int i = 0; i < depth; i++)
printf(" ");
printf("%d\n", h->element);
printf("left:\n");
dir(h->left,depth+1);
printf("right:\n");
dir(h->right, depth + 1);
printf("end\n");
}
}
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++)
h1=insert(a[i], h1);
for (; i < n; i++)
h2=insert(a[i], h2);
PriorityQueue h = merge(h1, h2);
int t;
scanf("%d", &t);
Delete(t, h);
while(!isEmpty(h)) {
printf("%d ", findMin(h));
h=deleteMin(h);
}
destroy(h);
}