メインページ | 構成 | ファイル一覧 | 構成メンバ | ファイルメンバ | 関連ページ

dkc2Tree.c

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

dkutil_cに対してSun Jul 18 22:45:21 2004に生成されました。 doxygen 1.3.6