《数据结构与算法分析——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); }