heap.c

来自「CMU大名鼎鼎的SPHINX-3大词汇量连续语音识别系统」· C语言 代码 · 共 237 行

C
237
字号
/* ==================================================================== * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer.  * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. * * This work was supported in part by funding from the Defense Advanced  * Research Projects Agency and the National Science Foundation of the  * United States of America, and the CMU Sphinx Speech Consortium. * * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * ==================================================================== * *//* * heap.c -- Generic heap structure for inserting in any and popping in sorted * 		order. * * ********************************************** * CMU ARPA Speech Project * * Copyright (c) 1999 Carnegie Mellon University. * ALL RIGHTS RESERVED. * ********************************************** *  * HISTORY *  * 05-Mar-99	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * 		Fixed bug in heap_destroy() (in while loop exit condition). *  * 23-Dec-96	M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University * 		Started. */#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "heap.h"#include "ckd_alloc.h"typedef struct heap_s {    void *data;		/* Application data at this node */    int32 val;		/* Associated with above application data; according to which			   heap is sorted (in ascending order) */    int32 nl, nr;	/* #left/right descendants of this node (for balancing heap) */    struct heap_s *l;	/* Root of left descendant heap */    struct heap_s *r;	/* Root of right descendant heap */} heapnode_t;#if 0static void heap_dump (heapnode_t *top, int32 level){    int32 i;        if (! top)	return;        for (i = 0; i < level; i++)	printf ("  ");    /* print top info */    heap_dump (top->l, level+1);    heap_dump (top->r, level+1);}#endifheap_t heap_new ( void ){    heapnode_t **h;        h = (heapnode_t **) ckd_calloc (1, sizeof(heapnode_t *));    *h = NULL;    return ((heap_t) h);}static heapnode_t *subheap_insert (heapnode_t *root, void *data, int32 val){    heapnode_t *h;    void *tmpdata;    int32 tmpval;        if (! root) {	h = (heapnode_t *) mymalloc (sizeof(heapnode_t));	h->data = data;	h->val = val;	h->l = h->r = NULL;	h->nl = h->nr = 0;	return h;    }    /* Root already exists; if new value is less, replace root node */    if (root->val > val) {	tmpdata = root->data;	tmpval = root->val;	root->data = data;	root->val = val;	data = tmpdata;	val = tmpval;    }    /* Insert new or old (replaced) node in right or left subtree; keep them balanced */    if (root->nl > root->nr) {	root->r = subheap_insert (root->r, data, val);	root->nr++;    } else {	root->l = subheap_insert (root->l, data, val);	root->nl++;    }    return root;}int32 heap_insert (heap_t heap, void *data, int32 val){    heapnode_t **hp;    hp = (heapnode_t **) heap;        *hp = subheap_insert (*hp, data, val);    return 0;}static heapnode_t *subheap_pop (heapnode_t *root){    heapnode_t *l, *r;    /* Propagate best value from below into root, if any */    l = root->l;    r = root->r;    if (! l) {	if (! r) {	    myfree ((char *) root, sizeof(heapnode_t));	    return NULL;	} else {	    root->data = r->data;	    root->val = r->val;	    root->r = subheap_pop (r);	    root->nr--;	}    } else {	if ((! r) || (l->val < r->val)) {	    root->data = l->data;	    root->val = l->val;	    root->l = subheap_pop (l);	    root->nl--;	} else {	    root->data = r->data;	    root->val = r->val;	    root->r = subheap_pop (r);	    root->nr--;	}    }    return root;}int32 heap_pop (heap_t heap, void **data, int32 *val){    heapnode_t **hp, *h;    hp = (heapnode_t **) heap;    h = *hp;    if (! h)	return 0;        *data = h->data;    *val = h->val;        *hp = subheap_pop (h);        return 1;}int32 heap_top (heap_t heap, void **data, int32 *val){    heapnode_t **hp, *h;    hp = (heapnode_t **) heap;    h = *hp;    if (! h)	return 0;        *data = h->data;    *val = h->val;        return 1;}int32 heap_destroy (heap_t heap){    void *data;    int32 val;        /* Empty the heap and free it */    while (heap_pop (heap, &data, &val) > 0);    ckd_free ((char *)heap);    return 0;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?