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

dkc2Tree.c

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

dkutil_cに対してTue Oct 19 03:34:54 2004に生成されました。 doxygen 1.3.6