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