- 论坛徽章:
- 0
|
- #include <stdio.h>
- #include <assert.h>
- #include <stdlib.h>
- #include <stddef.h>
- #include <string.h>
- /* compare keys of two records by lexical order */
- #define TCCMPLEXICAL(TC_rv, TC_aptr, TC_asiz, TC_bptr, TC_bsiz) \
- do { \
- (TC_rv) = 0; \
- int _TC_min = (TC_asiz) < (TC_bsiz) ? (TC_asiz) : (TC_bsiz); \
- for(int _TC_i = 0; _TC_i < _TC_min; _TC_i++){ \
- if(((unsigned char *)(TC_aptr))[_TC_i] != ((unsigned char *)(TC_bptr))[_TC_i]){ \
- (TC_rv) = ((unsigned char *)(TC_aptr))[_TC_i] - ((unsigned char *)(TC_bptr))[_TC_i]; \
- break; \
- } \
- } \
- if((TC_rv) == 0) (TC_rv) = (TC_asiz) - (TC_bsiz); \
- } while(false)
- /* Compare keys of two records by lexical order. */
- int tccmplexical(const char *aptr, int asiz, const char *bptr, int bsiz, void *op){
- assert(aptr && asiz >= 0 && bptr && bsiz >= 0);
- int rv;
- TCCMPLEXICAL(rv, aptr, asiz, bptr, bsiz);
- return rv;
- }
- typedef int (*TCCMP)(const char *aptr, int asiz, const char *bptr, int bsiz, void *op);
- typedef struct _TCTREEREC { /* type of structure for an element of a tree */
- int ksiz; /* size of the region of the key */
- int vsiz; /* size of the region of the value */
- char v[255];
- char k[255];
- struct _TCTREEREC *left; /* pointer to the left child */
- struct _TCTREEREC *right; /* pointer to the right child */
- } TCTREEREC;
- typedef struct { /* type of structure for a tree */
- TCTREEREC *root; /* pointer to the root element */
- TCTREEREC *cur; /* pointer to the current element */
- unsigned long long rnum; /* number of records */
- unsigned long long msiz; /* total size of records */
- TCCMP cmp; /* pointer to the comparison function */
- void *cmpop; /* opaque object for the comparison function */
- } TCTREE;
- TCTREEREC* tctreesplay(TCTREE *tree, const char *kbuf, int ksiz){
- assert(tree && kbuf && ksiz>=0);
- TCTREEREC *top = tree->root;
- if (!top) return NULL;
- TCCMP cmp = tree->cmp;
- void *cmpop = tree->cmpop;
- TCTREEREC ent;
- ent.left = NULL;
- ent.right = NULL;
- TCTREEREC *lrec = &ent;
- TCTREEREC *rrec = &ent;
- while (true) {
- char *dbuf = (char *)top + sizeof(*top);
- int cv = cmp(kbuf, ksiz, dbuf, top->ksiz, cmpop);
- if (cv < 0 ) {
- if(!top->left) break;
- dbuf = (char *)top->left + sizeof(*top);
- cv = cmp(kbuf, ksiz, dbuf, top->left->ksiz, cmpop);
- if(cv < 0){
- TCTREEREC *swap = top->left;
- top->left = swap->right;
- swap->right = top;
- top = swap;
- if(!top->left) break;
- }
- rrec->left = top;
- rrec = top;
- top = top->left;
- } else if (cv >0 ) {
- if(!top->right) break;
- dbuf = (char *)top->right + sizeof(*top);
- cv = cmp(kbuf, ksiz, dbuf, top->right->ksiz, cmpop);
- if(cv > 0){
- TCTREEREC *swap = top->right;
- top->right = swap->left;
- swap->left = top;
- top = swap;
- if(!top->right) break;
- }
- lrec->right = top;
- lrec = top;
- top = top->right;
- } else {
- break;
- }
- }
- lrec->right = top->left;
- rrec->left = top->right;
- top->left = ent.right;
- top->right = ent.left;
- return top;
- }
- /* Store a record into a tree object. */
- void tctreeput(TCTREE *tree, const char *kbuf, int ksiz, const char *vbuf, int vsiz){
- assert(tree && kbuf && ksiz >= 0 && vbuf && vsiz >= 0);
- TCTREEREC *top = tctreesplay(tree, kbuf, ksiz);
- if (!top){
- TCTREEREC *rec;
- rec = (TCTREEREC *)malloc(sizeof(*rec) + ksiz + vsiz + 1);
- char *dbuf = (char *)rec + sizeof(*rec);
- memcpy(dbuf, kbuf, ksiz);
- dbuf[ksiz] = '\0';
- rec->ksiz = ksiz;
- memcpy(dbuf + ksiz, vbuf, vsiz);
- dbuf[ksiz+vsiz] = '\0';
- rec->vsiz = vsiz;
- rec->left = NULL;
- rec->right = NULL;
- memcpy(rec->k, kbuf, ksiz);
- memcpy(rec->v, vbuf, vsiz);
- tree->root = rec;
- tree->rnum = 1;
- tree->msiz = ksiz + vsiz;
- return;
- }
- char *dbuf = (char *)top + sizeof(*top);
- int cv = tree->cmp(kbuf, ksiz, dbuf, top->ksiz, tree->cmpop);
- if(cv < 0){
- TCTREEREC *rec;
- rec = (TCTREEREC *)malloc(sizeof(*rec) + ksiz + vsiz + 1);
- char *dbuf = (char *)rec + sizeof(*rec);
- memcpy(dbuf, kbuf, ksiz);
- dbuf[ksiz] = '\0';
- rec->ksiz = ksiz;
- memcpy(dbuf + ksiz, vbuf, vsiz);
- dbuf[ksiz+vsiz] = '\0';
- rec->vsiz = vsiz;
- memcpy(rec->k, kbuf, ksiz);
- memcpy(rec->v, vbuf, vsiz);
- rec->left = top->left;
- rec->right = top;
- top->left = NULL;
- tree->rnum++;
- tree->msiz += ksiz + vsiz;
- tree->root = rec;
- } else if (cv>0) {
- TCTREEREC *rec;
- rec = (TCTREEREC *)malloc(sizeof(*rec) + ksiz + vsiz + 1);
- char *dbuf = (char *)rec + sizeof(*rec);
- memcpy(dbuf, kbuf, ksiz);
- dbuf[ksiz] = '\0';
- rec->ksiz = ksiz;
- memcpy(dbuf + ksiz, vbuf, vsiz);
- dbuf[ksiz+vsiz] = '\0';
- rec->vsiz = vsiz;
- memcpy(rec->k, kbuf, ksiz);
- memcpy(rec->v, vbuf, vsiz);
- rec->left = top;
- rec->right = top->right;
- top->right = NULL;
- tree->rnum++;
- tree->msiz += ksiz + vsiz;
- tree->root = rec;
- } else {
- tree->msiz += vsiz - top->vsiz;
- if(vsiz > top->vsiz){
- TCTREEREC *old = top;
- top = (TCTREEREC *)realloc(top,sizeof(*top) + ksiz + vsiz + 1);
- if(top != old){
- if(tree->cur == old) tree->cur = top;
- dbuf = (char *)top + sizeof(*top);
- }
- }
- memcpy(dbuf + ksiz, vbuf, vsiz);
- dbuf[ksiz+vsiz] = '\0';
- top->vsiz = vsiz;
- tree->root = top;
- }
- }
- /* Create a tree object with specifying the custom comparison function. */
- TCTREE *tctreenew2(TCCMP cmp, void *cmpop){
- assert(cmp);
- TCTREE *tree;
- tree = (TCTREE *)malloc(sizeof(*tree));
- tree->root = NULL;
- tree->cur = NULL;
- tree->rnum = 0;
- tree->msiz = 0;
- tree->cmp = cmp;
- tree->cmpop = cmpop;
- return tree;
- }
- int main(void)
- {
- TCTREE * tree = tctreenew2(tccmplexical, NULL);
-
- tctreeput(tree,"F", 1,"fff", 3);
- tctreeput(tree,"D", 1,"ddd", 3);
- tctreeput(tree,"E", 1,"eee", 3);
- tctreeput(tree,"H", 1,"hhh", 3);
- tctreeput(tree,"G", 1,"ggg", 3);
- tctreeput(tree,"B", 1,"bbb", 3);
- tctreeput(tree,"C", 1,"ccc", 3);
- tctreeput(tree,"I", 1,"iii", 3);
- /*
- tctreeput(tree,"N", 1,"nnn", 3);
- tctreeput(tree,"M", 1,"mmm", 3);
- tctreeput(tree,"L", 1,"lll", 3);
- tctreeput(tree,"K", 1,"kkk", 3);
- tctreeput(tree,"J", 1,"jjj", 3);
- tctreeput(tree,"I", 1,"iii", 3);
- tctreeput(tree,"H", 1,"hhh", 3);
- tctreeput(tree,"G", 1,"ggg", 3);
- */
-
- system("pause");
- return 0;
- }
复制代码 求大神解读一下这是种什么样的二叉排序树吧,它是如何进行存储排序的,程序可以在vc2008下运行 |
|