メインページ | アルファベット順一覧 | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkc2Tree.c

説明を見る。
00001 
00009 #define DKUTIL_C_2TREE_C
00010 
00011 #include "dkc2Tree.h"
00012 #include "dkcStdio.h"
00013 #include "dkcStack.h"
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 #if 0
00022 /* 番兵 
00023 static DKC_2TREE g2TreeSentinel={NULL,NULL,NULL,0,0};
00024 */
00025 
00026 static DKC_2TREE *dkcAlloc2TreeSentinel(){
00027     DKC_2TREE *p;
00028     p = dkcAllocate(sizeof(DKC_2TREE *));
00029     if(NULL==p) return NULL;
00030     //dkcAllocateでは領域すべてが0で初期化されている。
00031     p->mKey = INT_MIN;
00032     return p;
00033 }
00034 
00035 DKC_EXTERN BOOL WINAPI dkc2TreeIsSentinel(const DKC_2TREE *ptr)
00036 {
00037     dkcmNOT_ASSERT(NULL==ptr);
00038     return (ptr->mBuff == 0 && ptr->mSize == 0)
00039 }
00040 
00041 
00042 
00044 DKC_2TREE * WINAPI dkcAlloc2Tree(int Key)
00045 {
00046     DKC_2TREE *p;
00047     p = dkcAllocate(sizeof(DKC_2TREE));
00048     if(NULL==p) return NULL;
00049 
00050     //アロック
00051     p->mBuff = dkcAllocate(size);
00052     if(NULL==p->mBuff) goto Error;
00053     
00054     //データのコピー
00055     if(data){
00056         dkcmNOT_ASSERT(DKUTIL_FAILED(
00057             dkc_memcpy(p->mBuff,size,data,size)
00058         ));
00059     }
00060     //番兵を作る。
00061     p->mLeft = dkcAlloc2TreeSentinel();
00062     if(NULL==p->mLeft) goto Error;
00063     p->mRight = p->mLeft;
00064     
00065     p->mKey = Key;
00066     p->mSize = size;
00067 Error:
00068     dkcFree((void **)&p);
00069     return NULL;
00070 }
00071 
00073 DKC_INLINE void dkcFree2Tree(DKC_2TREE *ptr){
00074     dkcmNOT_ASSERT(TRUE==dkc2TreeIsSentinel(ptr));
00075     dkcFree((void **)&(ptr->mBuff));
00076     dkcFree((void **)&ptr);
00077 }
00078 
00080 DKC_INLINE int dkcFree2TreeWithStack(DKC_2TREE *ptr,DKC_STACK *ps)
00081 {
00082     DKC_2TREE *it = ptr;
00083     dkcmNOT_ASSERT(FALSE==dkc2TreeIsRoot(ptr));
00084     dkcmNOT_ASSERT(NULL==ptr || NULL==ps || ps->mOffsetOf != sizeof(DKC_2TREE *));
00085     //これで全部解放できるかは謎・・・。
00086     while(1){
00087         if(it->mLeft){
00088             dkcStackDynamicPush(ps,it->mLeft);
00089             it = it->mLeft;
00090             continue;
00091         }else if(it->mRight){
00092             dkcStackDynamicPush(ps,it->mRight);
00093             it = it->mRight;
00094             continue
00095         }else{
00096             dkcFree2Tree(it);
00097             if(DKUTIL_FAILED(dkcStackTop(ps,it))){
00098                 break;
00099             }
00100             dkcStackPop(ps);
00101         }
00102     }
00103 
00104     return edk_SUCCEEDED;
00105 
00106 }
00107 
00108 int WINAPI dkcFree2TreeRoot(DKC_2TREE **ptr){
00109     DKC_2TREE *begin,*it;
00110     DKC_STACK *stack;
00111     int result;
00112     
00113     if(NULL==ptr || NULL==*ptr){return edk_ArgumentException;}
00114     
00115     stack = dkcAllocStack(100,sizeof(DKC_2TREE *));
00116     if(NULL==stack) return edk_FAILED;
00117 
00118     begin = (*ptr);
00119     result = dkcFree2TreeWithStack((*ptr),ps);
00120     (*ptr) = NULL;
00121     dkcFreeStack(&stack);
00122 
00123     return result;
00124 
00125 }
00126 
00127 static DKC_2TREE *dkcAlloc2TreeInsertPoint(DKC_2TREE *ptr,int Key){
00128 
00129 
00130 }
00131 
00132 int WINAPI dkc2TreeInsert(DKC_2TREE *ptr,int Key,const void *data,size_t size);
00133 
00134 
00135 int WINAPI dkc2TreeChain(DKC_2TREE *dest,DKC_2TREE *src);
00136 
00137 int WINAPI dkc2TreeEraseFromAddress
00138 
00139 
00140 
00141 int WINAPI dkc2TreeEraseFromKey(DKC_2TREEROOT *ptr,int Key){
00142     DKC_2TREE *it,*prev;
00143     int isLeft,isRight;
00144     dkcmNOT_ASSERT(NULL==ptr || NULL== ptr->mTree || NULL==ptr->mSentinel);
00145 
00146 
00147     //準備
00148     prev = NULL;
00149     //番兵に入れる。
00150     ptr->mSentinel->mKey = Key;
00151     //tree pointer
00152     it = ptr->mTree;
00153     for(;;){
00154         if(it->mKey == Key){//同じのみっけ!
00155             break;
00156         }else if(it->mKey < Key){//でっかい
00157             prev = it;
00158             it = it->mRight;
00159         }else{//ちっこい
00160             prev = it
00161             it = it->mLeft;
00162         }
00163     }
00164     if(it == ptr->mSentinel) return edk_FAILED;
00165 
00166     isLeft = (it->mLeft != ptr->mSentinel);
00167     isRight = (it->mRight != ptr->mSentinel);
00168 
00169     //どちらもない。
00170     if( !isLeft && !isRight) return edk_SUCCEEDED;
00171 
00172     if (isLeft){
00173         
00174     }
00175     if(isRight){//right
00176 
00177     }
00178         prev->mRight = it->mRight;
00179     }else if(it->mRight == ptr->mSentinel){
00180         prev->mRight = it->mLeft;
00181     }else {
00182         q = &(r->left);
00183         while ((*q)->right != &nil) q = &((*q)->right);
00184         s = *q;  *q = s->left;
00185         s->left = r->left;  s->right = r->right;
00186         *p = s;
00187     }
00188 }
00189 
00190 DKC_2TREE * WINAPI dkc2TreeSearchWithStack(DKC_2TREE *ptr,DKC_STACK *ps,int Key)
00191 {
00192     
00193 
00194     
00195 
00196 }
00197 
00198 
00199 
00200 DKC_2TREE * WINAPI dkc2TreeSearch(DKC_2TREEROOT *ptr,int Key)
00201 {
00202     DKC_2TREE *it = ptr->mTree;
00203     //番兵に入れる。
00204     ptr->mSentinel->mKey = Key;
00205     
00206     while(it->mKey != Key){
00207         if(it->mKey < Key){//でっかい
00208             it = it->mRight;
00209         }else{//ちっこい
00210             it = it->mLeft;
00211         }
00212     }
00213     if(it == ptr->mSentinel) return NULL;
00214     return it;
00215 }
00216 
00217 
00218 int WINAPI dkc2TreeGetBuffer(DKC_2TREE *ptr,void *data,size_t size);
00219 
00220 int WINAPI dkc2TreeSetBuffer(DKC_2TREE *ptr,void *data,size_t size);
00221 
00222 
00223 
00224 #include <stdio.h>
00225 #include <stdlib.h>
00226 #include <string.h>
00227 
00228 typedef char keytype[21];
00229 
00230 typedef struct node {
00231     struct node *left, *right;
00232     keytype key;
00233 } *nodeptr;
00234 
00235 struct node nil;
00236 nodeptr root = &nil;
00237 
00238 nodeptr insert(keytype key)  /* 挿入 (登録) */
00239 {
00240     int cmp;
00241     nodeptr *p, q;
00242 
00243     strcpy(nil.key, key);  /* 番人 */
00244     p = &root;
00245     while ((cmp = strcmp(key, (*p)->key)) != 0)
00246         if (cmp < 0) p = &((*p)->left );
00247         else         p = &((*p)->right);
00248     if (*p != &nil) return NULL;  /* すでに登録されている */
00249     if ((q = malloc(sizeof *q)) == NULL) {
00250         printf("メモリ不足.\n");  exit(EXIT_FAILURE);
00251     }
00252     strcpy(q->key, key);
00253     q->left = &nil;  q->right = *p;  *p = q;
00254     return q;  /* 登録した */
00255 }
00256 
00257 int delete(keytype key)  /* 削除できれば 0, 失敗なら 1 を返す */
00258 {
00259     int cmp;
00260     nodeptr *p, *q, r, s;
00261 
00262     strcpy(nil.key, key);  /* 番人 */
00263     p = &root;
00264     while ((cmp = strcmp(key, (*p)->key)) != 0)
00265         if (cmp < 0) p = &((*p)->left);
00266         else         p = &((*p)->right);
00267     if (*p == &nil) return 1;  /* 見つからず */
00268     r = *p;
00269     if      (r->right == &nil) *p = r->left;
00270     else if (r->left  == &nil) *p = r->right;
00271     else {
00272         q = &(r->left);
00273         while ((*q)->right != &nil) q = &((*q)->right);
00274         s = *q;  *q = s->left;
00275         s->left = r->left;  s->right = r->right;
00276         *p = s;
00277     }
00278     free(r);
00279     return 0;  /* 削除成功 */
00280 }
00281 
00282 nodeptr search(keytype key)  /* 検索 (未登録ならNULLを返す) */
00283 {
00284     int cmp;
00285     nodeptr p;
00286 
00287     strcpy(nil.key, key);  /* 番人 */
00288     p = root;
00289     while ((cmp = strcmp(key, p->key)) != 0)
00290         if (cmp < 0) p = p->left;
00291         else         p = p->right;
00292     if (p != &nil) return p;     /* 見つかった */
00293     else           return NULL;  /* 見つからない */
00294 }
00295 
00296 void printtree(nodeptr p)
00297 {
00298     static int depth = 0;
00299 
00300     if (p->left != &nil) {
00301         depth++;  printtree(p->left);  depth--;
00302     }
00303     printf("%*c%s\n", 5 * depth, ' ', p->key);
00304     if (p->right != &nil) {
00305         depth++;  printtree(p->right);  depth--;
00306     }
00307 }
00308 
00309 int main()
00310 {
00311     char buf[22];
00312 
00313     printf("命令 Iabc:  abcを挿入\n"
00314            "     Dabc:  abcを削除\n"
00315            "     Sabc:  abcを検索\n");
00316     for ( ; ; ) {
00317         printf("命令? ");
00318         if (scanf("%21s%*[^\n]", buf) != 1) break;
00319         switch (buf[0]) {
00320         case 'I':  case 'i':
00321             if (insert(&buf[1])) printf("登録しました.\n");
00322             else                 printf("登録ずみです.\n");
00323             break;
00324         case 'D':  case 'd':
00325             if (delete(&buf[1])) printf("登録されていません.\n");
00326             else                 printf("削除しました.\n");
00327             break;
00328         case 'S':  case 's':
00329             if (search(&buf[1])) printf("登録されています.\n");
00330             else                 printf("登録されていません\n");
00331             break;
00332         default:
00333             printf("使えるのは I, D, S です.\n");
00334             break;
00335         }
00336         if (root != &nil) {
00337             printf("\n");  printtree(root);  printf("\n");
00338         }
00339     }
00340     return EXIT_SUCCESS;
00341 }
00342 
00343 #endif

dkutil_cに対してTue Dec 7 01:09:56 2004に生成されました。 doxygen 1.3.6