亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? hash.c

?? 一些常用的數據結構庫
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* * Hash Table Data Type * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net> * * Free Software License: * * All rights are reserved by the author, with the following exceptions: * Permission is granted to freely reproduce and distribute this software, * possibly in exchange for a fee, provided that this copyright notice appears * intact. Permission is also granted to adapt this software to produce * derivative works, as long as the modified versions carry this copyright * notice and additional notices stating that the work has been modified. * This source code may be translated into executable form and incorporated * into proprietary software; there is no requirement for such software to * contain a copyright notice related to this source. * * $Id: hash.c,v 1.36.2.11 2000/11/13 01:36:45 kaz Exp $ * $Name: kazlib_1_20 $ */#include <stdlib.h>#include <stddef.h>#include <assert.h>#include <string.h>#define HASH_IMPLEMENTATION#include "hash.h"#ifdef KAZLIB_RCSIDstatic const char rcsid[] = "$Id: hash.c,v 1.36.2.11 2000/11/13 01:36:45 kaz Exp $";#endif#define INIT_BITS	6#define INIT_SIZE	(1UL << (INIT_BITS))	/* must be power of two		*/#define INIT_MASK	((INIT_SIZE) - 1)#define next hash_next#define key hash_key#define data hash_data#define hkey hash_hkey#define table hash_table#define nchains hash_nchains#define nodecount hash_nodecount#define maxcount hash_maxcount#define highmark hash_highmark#define lowmark hash_lowmark#define compare hash_compare#define function hash_function#define allocnode hash_allocnode#define freenode hash_freenode#define context hash_context#define mask hash_mask#define dynamic hash_dynamic#define table hash_table#define chain hash_chainstatic hnode_t *hnode_alloc(void *context);static void hnode_free(hnode_t *node, void *context);static hash_val_t hash_fun_default(const void *key);static int hash_comp_default(const void *key1, const void *key2);int hash_val_t_bit;/* * Compute the number of bits in the hash_val_t type.  We know that hash_val_t * is an unsigned integral type. Thus the highest value it can hold is a * Mersenne number (power of two, less one). We initialize a hash_val_t * object with this value and then shift bits out one by one while counting. * Notes: * 1. HASH_VAL_T_MAX is a Mersenne number---one that is one less than a power *    of two. This means that its binary representation consists of all one *    bits, and hence ``val'' is initialized to all one bits. * 2. While bits remain in val, we increment the bit count and shift it to the *    right, replacing the topmost bit by zero. */static void compute_bits(void){    hash_val_t val = HASH_VAL_T_MAX;	/* 1 */    int bits = 0;    while (val) {	/* 2 */	bits++;	val >>= 1;    }    hash_val_t_bit = bits;}/* * Verify whether the given argument is a power of two. */static int is_power_of_two(hash_val_t arg){    if (arg == 0)	return 0;    while ((arg & 1) == 0)	arg >>= 1;    return (arg == 1);}/* * Compute a shift amount from a given table size  */static hash_val_t compute_mask(hashcount_t size){    assert (is_power_of_two(size));    assert (size >= 2);    return size - 1;}/* * Initialize the table of pointers to null. */static void clear_table(hash_t *hash){    hash_val_t i;    for (i = 0; i < hash->nchains; i++)	hash->table[i] = NULL;}/* * Double the size of a dynamic table. This works as follows. Each chain splits * into two adjacent chains.  The shift amount increases by one, exposing an * additional bit of each hashed key. For each node in the original chain, the * value of this newly exposed bit will decide which of the two new chains will * receive the node: if the bit is 1, the chain with the higher index will have * the node, otherwise the lower chain will receive the node. In this manner, * the hash table will continue to function exactly as before without having to * rehash any of the keys. * Notes: * 1.  Overflow check. * 2.  The new number of chains is twice the old number of chains. * 3.  The new mask is one bit wider than the previous, revealing a *     new bit in all hashed keys. * 4.  Allocate a new table of chain pointers that is twice as large as the *     previous one. * 5.  If the reallocation was successful, we perform the rest of the growth *     algorithm, otherwise we do nothing. * 6.  The exposed_bit variable holds a mask with which each hashed key can be *     AND-ed to test the value of its newly exposed bit. * 7.  Now loop over each chain in the table and sort its nodes into two *     chains based on the value of each node's newly exposed hash bit. * 8.  The low chain replaces the current chain.  The high chain goes *     into the corresponding sister chain in the upper half of the table. * 9.  We have finished dealing with the chains and nodes. We now update *     the various bookeeping fields of the hash structure. */static void grow_table(hash_t *hash){    hnode_t **newtable;    assert (2 * hash->nchains > hash->nchains);	/* 1 */    newtable = realloc(hash->table,	    sizeof *newtable * hash->nchains * 2);	/* 4 */    if (newtable) {	/* 5 */	hash_val_t mask = (hash->mask << 1) | 1;	/* 3 */	hash_val_t exposed_bit = mask ^ hash->mask;	/* 6 */	hash_val_t chain;	assert (mask != hash->mask);	for (chain = 0; chain < hash->nchains; chain++) { /* 7 */	    hnode_t *low_chain = 0, *high_chain = 0, *hptr, *next;	    for (hptr = newtable[chain]; hptr != 0; hptr = next) {		next = hptr->next;		if (hptr->hkey & exposed_bit) {		    hptr->next = high_chain;		    high_chain = hptr;		} else {		    hptr->next = low_chain;		    low_chain = hptr;		}	    }	    newtable[chain] = low_chain; 	/* 8 */	    newtable[chain + hash->nchains] = high_chain;	}	hash->table = newtable;			/* 9 */	hash->mask = mask;	hash->nchains *= 2;	hash->lowmark *= 2;	hash->highmark *= 2;    }    assert (hash_verify(hash));}/* * Cut a table size in half. This is done by folding together adjacent chains * and populating the lower half of the table with these chains. The chains are * simply spliced together. Once this is done, the whole table is reallocated * to a smaller object. * Notes: * 1.  It is illegal to have a hash table with one slot. This would mean that *     hash->shift is equal to hash_val_t_bit, an illegal shift value. *     Also, other things could go wrong, such as hash->lowmark becoming zero. * 2.  Looping over each pair of sister chains, the low_chain is set to *     point to the head node of the chain in the lower half of the table,  *     and high_chain points to the head node of the sister in the upper half. * 3.  The intent here is to compute a pointer to the last node of the *     lower chain into the low_tail variable. If this chain is empty, *     low_tail ends up with a null value. * 4.  If the lower chain is not empty, we simply tack the upper chain onto it. *     If the upper chain is a null pointer, nothing happens. * 5.  Otherwise if the lower chain is empty but the upper one is not, *     If the low chain is empty, but the high chain is not, then the *     high chain is simply transferred to the lower half of the table. * 6.  Otherwise if both chains are empty, there is nothing to do. * 7.  All the chain pointers are in the lower half of the table now, so *     we reallocate it to a smaller object. This, of course, invalidates *     all pointer-to-pointers which reference into the table from the *     first node of each chain. * 8.  Though it's unlikely, the reallocation may fail. In this case we *     pretend that the table _was_ reallocated to a smaller object. * 9.  Finally, update the various table parameters to reflect the new size. */static void shrink_table(hash_t *hash){    hash_val_t chain, nchains;    hnode_t **newtable, *low_tail, *low_chain, *high_chain;    assert (hash->nchains >= 2);			/* 1 */    nchains = hash->nchains / 2;    for (chain = 0; chain < nchains; chain++) {	low_chain = hash->table[chain];		/* 2 */	high_chain = hash->table[chain + nchains];	for (low_tail = low_chain; low_tail && low_tail->next; low_tail = low_tail->next)	    ;	/* 3 */	if (low_chain != 0)				/* 4 */	    low_tail->next = high_chain;	else if (high_chain != 0)			/* 5 */	    hash->table[chain] = high_chain;	else	    assert (hash->table[chain] == NULL);	/* 6 */    }    newtable = realloc(hash->table,	    sizeof *newtable * nchains);		/* 7 */    if (newtable)					/* 8 */	hash->table = newtable;    hash->mask >>= 1;			/* 9 */    hash->nchains = nchains;    hash->lowmark /= 2;    hash->highmark /= 2;    assert (hash_verify(hash));}/* * Create a dynamic hash table. Both the hash table structure and the table * itself are dynamically allocated. Furthermore, the table is extendible in * that it will automatically grow as its load factor increases beyond a * certain threshold. * Notes: * 1. If the number of bits in the hash_val_t type has not been computed yet, *    we do so here, because this is likely to be the first function that the *    user calls. * 2. Allocate a hash table control structure. * 3. If a hash table control structure is successfully allocated, we *    proceed to initialize it. Otherwise we return a null pointer. * 4. We try to allocate the table of hash chains. * 5. If we were able to allocate the hash chain table, we can finish *    initializing the hash structure and the table. Otherwise, we must *    backtrack by freeing the hash structure. * 6. INIT_SIZE should be a power of two. The high and low marks are always set *    to be twice the table size and half the table size respectively. When the *    number of nodes in the table grows beyond the high size (beyond load *    factor 2), it will double in size to cut the load factor down to about *    about 1. If the table shrinks down to or beneath load factor 0.5, *    it will shrink, bringing the load up to about 1. However, the table *    will never shrink beneath INIT_SIZE even if it's emptied. * 7. This indicates that the table is dynamically allocated and dynamically *    resized on the fly. A table that has this value set to zero is *    assumed to be statically allocated and will not be resized. * 8. The table of chains must be properly reset to all null pointers. */hash_t *hash_create(hashcount_t maxcount, hash_comp_t compfun,	hash_fun_t hashfun){    hash_t *hash;    if (hash_val_t_bit == 0)	/* 1 */	compute_bits();    hash = malloc(sizeof *hash);	/* 2 */    if (hash) {		/* 3 */	hash->table = malloc(sizeof *hash->table * INIT_SIZE);	/* 4 */	if (hash->table) {	/* 5 */	    hash->nchains = INIT_SIZE;		/* 6 */	    hash->highmark = INIT_SIZE * 2;	    hash->lowmark = INIT_SIZE / 2;	    hash->nodecount = 0;	    hash->maxcount = maxcount;	    hash->compare = compfun ? compfun : hash_comp_default;	    hash->function = hashfun ? hashfun : hash_fun_default;	    hash->allocnode = hnode_alloc;	    hash->freenode = hnode_free;	    hash->context = NULL;	    hash->mask = INIT_MASK;	    hash->dynamic = 1;			/* 7 */	    clear_table(hash);			/* 8 */	    assert (hash_verify(hash));	    return hash;	} 	free(hash);    }    return NULL;}/* * Select a different set of node allocator routines. */void hash_set_allocator(hash_t *hash, hnode_alloc_t al,	hnode_free_t fr, void *context){    assert (hash_count(hash) == 0);    assert ((al == 0 && fr == 0) || (al != 0 && fr != 0));    hash->allocnode = al ? al : hnode_alloc;    hash->freenode = fr ? fr : hnode_free;    hash->context = context;}/* * Free every node in the hash using the hash->freenode() function pointer, and * cause the hash to become empty. */void hash_free_nodes(hash_t *hash){    hscan_t hs;    hnode_t *node;    hash_scan_begin(&hs, hash);    while ((node = hash_scan_next(&hs))) {	hash_scan_delete(hash, node);	hash->freenode(node, hash->context);    }    hash->nodecount = 0;    clear_table(hash);}/* * Obsolescent function for removing all nodes from a table, * freeing them and then freeing the table all in one step. */void hash_free(hash_t *hash){#ifdef KAZLIB_OBSOLESCENT_DEBUG    assert ("call to obsolescent function hash_free()" && 0);#endif    hash_free_nodes(hash);    hash_destroy(hash);}/* * Free a dynamic hash table structure. */void hash_destroy(hash_t *hash){    assert (hash_val_t_bit != 0);    assert (hash_isempty(hash));    free(hash->table);    free(hash);}/* * Initialize a user supplied hash structure. The user also supplies a table of * chains which is assigned to the hash structure. The table is static---it * will not grow or shrink. * 1. See note 1. in hash_create(). * 2. The user supplied array of pointers hopefully contains nchains nodes. * 3. See note 7. in hash_create(). * 4. We must dynamically compute the mask from the given power of two table *    size.  * 5. The user supplied table can't be assumed to contain null pointers, *    so we reset it here. */hash_t *hash_init(hash_t *hash, hashcount_t maxcount,	hash_comp_t compfun, hash_fun_t hashfun, hnode_t **table,	hashcount_t nchains){    if (hash_val_t_bit == 0)	/* 1 */	compute_bits();    assert (is_power_of_two(nchains));    hash->table = table;	/* 2 */    hash->nchains = nchains;    hash->nodecount = 0;    hash->maxcount = maxcount;    hash->compare = compfun ? compfun : hash_comp_default;    hash->function = hashfun ? hashfun : hash_fun_default;    hash->dynamic = 0;		/* 3 */    hash->mask = compute_mask(nchains);	/* 4 */    clear_table(hash);		/* 5 */    assert (hash_verify(hash));    return hash;}/* * Reset the hash scanner so that the next element retrieved by * hash_scan_next() shall be the first element on the first non-empty chain.  * Notes: * 1. Locate the first non empty chain. * 2. If an empty chain is found, remember which one it is and set the next *    pointer to refer to its first element. * 3. Otherwise if a chain is not found, set the next pointer to NULL *    so that hash_scan_next() shall indicate failure. */void hash_scan_begin(hscan_t *scan, hash_t *hash){    hash_val_t nchains = hash->nchains;    hash_val_t chain;    scan->table = hash;    /* 1 */    for (chain = 0; chain < nchains && hash->table[chain] == 0; chain++)	;    if (chain < nchains) {	/* 2 */	scan->chain = chain;	scan->next = hash->table[chain];    } else {			/* 3 */	scan->next = NULL;    }}/* * Retrieve the next node from the hash table, and update the pointer * for the next invocation of hash_scan_next().  * Notes: * 1. Remember the next pointer in a temporary value so that it can be *    returned. * 2. This assertion essentially checks whether the module has been properly *    initialized. The first point of interaction with the module should be *    either hash_create() or hash_init(), both of which set hash_val_t_bit to *    a non zero value. * 3. If the next pointer we are returning is not NULL, then the user is *    allowed to call hash_scan_next() again. We prepare the new next pointer *    for that call right now. That way the user is allowed to delete the node *    we are about to return, since we will no longer be needing it to locate *    the next node. * 4. If there is a next node in the chain (next->next), then that becomes the *    new next node, otherwise ... * 5. We have exhausted the current chain, and must locate the next subsequent *    non-empty chain in the table. * 6. If a non-empty chain is found, the first element of that chain becomes *    the new next node. Otherwise there is no new next node and we set the *    pointer to NULL so that the next time hash_scan_next() is called, a null *    pointer shall be immediately returned. */hnode_t *hash_scan_next(hscan_t *scan){    hnode_t *next = scan->next;		/* 1 */    hash_t *hash = scan->table;    hash_val_t chain = scan->chain + 1;    hash_val_t nchains = hash->nchains;    assert (hash_val_t_bit != 0);	/* 2 */    if (next) {			/* 3 */	if (next->next) {	/* 4 */	    scan->next = next->next;	} else {	    while (chain < nchains && hash->table[chain] == 0)	/* 5 */	    	chain++;	    if (chain < nchains) {	/* 6 */		scan->chain = chain;		scan->next = hash->table[chain];	    } else {		scan->next = NULL;	    }	}    }    return next;}/* * Insert a node into the hash table. * Notes: * 1. It's illegal to insert more than the maximum number of nodes. The client *    should verify that the hash table is not full before attempting an *    insertion. * 2. The same key may not be inserted into a table twice. * 3. If the table is dynamic and the load factor is already at >= 2, *    grow the table. * 4. We take the bottom N bits of the hash value to derive the chain index, *    where N is the base 2 logarithm of the size of the hash table.  */void hash_insert(hash_t *hash, hnode_t *node, const void *key)

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91福利社在线观看| 中文字幕亚洲一区二区va在线| 亚洲日本va在线观看| 色狠狠色狠狠综合| 极品瑜伽女神91| 中文字幕综合网| 久久久久国产精品人| 在线看国产一区二区| 国产精品18久久久久久久网站| 国产精品视频免费| 久久久影院官网| 欧美日韩午夜影院| 国产成人午夜高潮毛片| 午夜精品久久久| 国产精品超碰97尤物18| 26uuu另类欧美| 日韩一区二区免费高清| 欧洲视频一区二区| 色综合咪咪久久| av成人老司机| av在线一区二区| 久久机这里只有精品| 成人欧美一区二区三区白人| 国产香蕉久久精品综合网| 欧美一区二区三区人| 日本韩国一区二区三区视频| 成人动漫视频在线| 国产成人精品亚洲777人妖| 韩国v欧美v日本v亚洲v| 六月婷婷色综合| 亚洲国产电影在线观看| 国产女人aaa级久久久级| 国产日产欧美一区二区视频| 精品福利二区三区| 国产精品久久久久久久久久久免费看 | 91色婷婷久久久久合中文| 99re热这里只有精品视频| 成人av网址在线观看| 成人免费精品视频| 在线免费观看不卡av| 欧美三级日韩三级| 日韩免费一区二区三区在线播放| 欧美肥胖老妇做爰| 久久久久国产成人精品亚洲午夜| 精品99999| 一区二区三区四区在线播放| 日韩精品一级中文字幕精品视频免费观看| 日本不卡一区二区三区| 国产99久久久国产精品潘金| 成人国产免费视频| 日韩欧美国产高清| 欧美国产精品专区| 久久er99精品| 欧美日韩另类一区| 国产亚洲一二三区| 视频一区二区中文字幕| 高清国产一区二区| 久久婷婷色综合| 偷窥少妇高潮呻吟av久久免费| 国产激情一区二区三区四区| 欧美午夜影院一区| 中文字幕不卡在线观看| 国产一区二区三区免费观看| www.爱久久.com| 中文字幕制服丝袜成人av| 春色校园综合激情亚洲| xfplay精品久久| 欧美色欧美亚洲另类二区| 日本大胆欧美人术艺术动态| 欧美国产日产图区| 日韩一区二区在线免费观看| 91小视频在线免费看| 国产精品中文字幕欧美| 午夜成人免费电影| 亚洲欧美日韩人成在线播放| 色屁屁一区二区| 午夜精品一区二区三区电影天堂| 日韩色视频在线观看| 粉嫩aⅴ一区二区三区四区| 亚洲免费成人av| 欧美精品一区二区久久久| 国产91综合网| 天堂久久久久va久久久久| 欧美日韩免费电影| 粉嫩蜜臀av国产精品网站| 午夜av电影一区| 国产精品国产三级国产专播品爱网| 欧美剧在线免费观看网站| 国产成a人亚洲| 另类专区欧美蜜桃臀第一页| 国产午夜一区二区三区| 欧美亚洲国产一区在线观看网站| 激情丁香综合五月| 性久久久久久久久久久久| 国产欧美一区二区三区在线老狼| 欧美色视频在线| 99国产精品久久久久久久久久久| 蜜桃av噜噜一区| 亚洲一区二区高清| 亚洲一二三四区| 狠狠色伊人亚洲综合成人| 91麻豆免费视频| 国产一区在线看| 高清av一区二区| 欧美亚洲愉拍一区二区| 欧美另类一区二区三区| 久久精品国产999大香线蕉| 欧美一区二区三区公司| 日韩一区二区电影网| 国产视频911| 亚洲成人动漫一区| 国产在线看一区| 日本道色综合久久| 91精品国产色综合久久| 国产精品久久久久久久午夜片| 亚洲老妇xxxxxx| 国产精品一品二品| 欧美日韩精品福利| 国产精品乱码一区二区三区软件| 亚洲伊人色欲综合网| 国产精品系列在线观看| 欧美视频在线一区| 国产精品久久777777| 久草中文综合在线| 欧美日韩精品欧美日韩精品一综合| 奇米777欧美一区二区| 亚洲欧洲av在线| 在线观看免费亚洲| 日韩电影免费在线| 国产精品国产成人国产三级| 精品黑人一区二区三区久久| 欧美日韩亚洲另类| www..com久久爱| 91丨九色丨蝌蚪富婆spa| 色婷婷精品大在线视频| 99精品国产视频| 粉嫩av亚洲一区二区图片| 国产成人精品1024| 国产成人精品aa毛片| 在线看国产一区二区| 日本韩国欧美三级| 日韩欧美中文一区| 久久一日本道色综合| 国产欧美视频在线观看| 欧美国产精品专区| 亚洲精品乱码久久久久久| 一区二区在线看| 国产精品白丝jk白祙喷水网站| 国产一二精品视频| 91亚洲男人天堂| 日韩欧美国产1| 一区二区三区资源| 蜜桃av一区二区三区| 欧美日韩免费不卡视频一区二区三区| 91.成人天堂一区| 一区二区视频在线| 久久99久久久久| 欧美男女性生活在线直播观看| 色婷婷久久久久swag精品| 成人高清在线视频| 国产美女久久久久| 欧美精品一区二区久久婷婷| 欧美年轻男男videosbes| 色综合久久88色综合天天免费| 蜜臀av性久久久久蜜臀aⅴ四虎| 国产精品乱码人人做人人爱| 日本麻豆一区二区三区视频| av福利精品导航| 日韩免费电影一区| 夜夜爽夜夜爽精品视频| 国产在线不卡一卡二卡三卡四卡| 欧美性色欧美a在线播放| 国产亚洲人成网站| 全国精品久久少妇| 在线精品视频免费观看| 国产精品三级久久久久三级| 久久国内精品视频| 欧美日韩mp4| 一级日本不卡的影视| 风流少妇一区二区| 精品国产一区二区国模嫣然| 亚洲成人综合在线| 色综合天天综合网天天狠天天| 国产色综合一区| 国产乱码精品一区二区三区五月婷| 7777精品伊人久久久大香线蕉 | 日韩在线一二三区| 色欧美片视频在线观看 | 日韩高清在线电影| 欧美性生活一区| 亚洲自拍偷拍图区| 色狠狠桃花综合| 亚洲欧美成人一区二区三区| 成人免费观看视频| 国产精品青草久久| 99久久久国产精品| 国产精品毛片高清在线完整版| 国产美女视频91| 亚洲国产激情av| 99综合电影在线视频|