スポンサーリンク
ツリー構造のデータ構造
構造体で下記のように表現しています。
各ノードには、値と左右のノードへのポインタを定義しています。
typedef struct node{ int value; struct node* pLeftNode; struct node* pRightNode; }node_t;
また、ツリー構造の先頭を定義するため、別途tree_tを定義しています。
typedef struct tree{ node_t* pRootNode; }tree_t;
スポンサーリンク
ツリー構造の各関数
まずは、実際にツリーにノードを挿入する関数です。
ツリーの先頭から各ノードをたどって行き、登録されていなければ、新しくノードを作成してvalueを格納します。
挿入しようとしているvalueとノードのvalueを比較して、挿入しようとしているvalueが小さければ左のノードを、大きければ右のノードをたどって行きます。再帰関数で実現しています。
node_t* insertNode(node_t* pNode, int value){ if(pNode == NULL){ return initNode(value); } if(value == pNode->value){ printf("already registered\n"); }else if(value < pNode->value){ pNode->pLeftNode = insertNode(pNode->pLeftNode, value); }else{ pNode->pRightNode = insertNode(pNode->pRightNode, value); } return pNode; } int insertNodeInTree(tree_t* pTree, int value){ node_t* pNode = NULL; if(pTree == NULL){ printf("arg chk error"); return -1; } pTree->pRootNode = insertNode(pTree->pRootNode, value); printfTree(pTree); return 0; }
下記は、ノードを実際に作成するサブ関数になります。
メモリを確保して、値を代入します。
終端ノードになるので、左右のノードへのポインタにはNULLを代入します。
node_t* initNode(int value){ node_t* pNode = NULL; pNode = (node_t*)malloc(sizeof(node_t)); if(pNode == NULL){ printf("malloc error\n"); return NULL; } pNode->value = value; pNode->pLeftNode = NULL; pNode->pRightNode = NULL; return pNode; }
下記は、各ノードのメモリを解放する関数になります。
再帰関数で全てのノードを順にたどって行き、free()していきます。
void freeNode(node_t* pNode){ if(pNode == NULL){ return; } freeNode(pNode->pLeftNode); freeNode(pNode->pRightNode); free(pNode); return; } int freeNodeInTree(tree_t* pTree){ if(pTree == NULL){ printf("arg chk error"); return -1; } freeNode(pTree->pRootNode); pTree->pRootNode = NULL; printfTree(pTree); return 0; }
ツリーの中の最大値と階層レベルを表示する関数です。
ツリーの先頭から終端ノードに行き着くまで、右のノードをたどって行きます。
右終端ノードに最大値が格納されています。
int printfMaxAndLevel(tree_t* pTree){ node_t* pNode = NULL; int level = 1; if(pTree == NULL){ printf("arg chk error"); return -1; } if(pTree->pRootNode == NULL){ printf("No node\n"); return -1; } pNode = pTree->pRootNode; while(pNode->pRightNode != NULL){ pNode = pNode->pRightNode; level++; } printf("max=%d level=%d\n", pNode->value, level); return -1; }
ツリーの中の最小値と階層レベルを表示する関数です。
ツリーの先頭から終端ノードに行き着くまで、左のノードをたどって行きます。
左終端ノードに最小値が格納されています。
int printfMinAndLevel(tree_t* pTree){ node_t* pNode = NULL; int level = 1; if(pTree == NULL){ printf("arg chk error"); return -1; } if(pTree->pRootNode == NULL){ printf("No node\n"); return -1; } pNode = pTree->pRootNode; while(pNode->pLeftNode != NULL){ pNode = pNode->pLeftNode; level++; } printf("min=%d level=%d\n", pNode->value, level); return -1; }
下記は、ツリーに指定したvalueの値が格納されているノードが存在するかを表示する関数になります。
再帰関数で全てのノードをたどって行きます。
int findNode(node_t* pNode, int value){ if(pNode == NULL){ return -1; } if(value == pNode->value){ return 0; }else if(value < pNode->value){ return findNode(pNode->pLeftNode, value); }else{ return findNode(pNode->pRightNode, value); } } int findNodeInTree(tree_t* pTree, int value){ if(pTree == NULL){ printf("arg chk error"); return -1; } if(findNode(pTree->pRootNode, value) == 0){ printf("existed\n"); }else{ printf("Not existed\n"); } return 0; }
スポンサーリンク
サンプルコード
下記がサンプルコードになります。
#include #include typedef struct node{ int value; struct node* pLeftNode; struct node* pRightNode; }node_t; typedef struct tree{ node_t* pRootNode; }tree_t; void printfNode(node_t* pNode){ if(pNode == NULL){ printf("No node\n"); return; } printf("%d\n", pNode->value); printf("Left "); printfNode(pNode->pLeftNode); printf("Right "); printfNode(pNode->pRightNode); return; } void printfTree(tree_t* pTree){ if(pTree == NULL){ printf("arg chk error"); return; } printf("Root "); printfNode(pTree->pRootNode); printf("\n"); return; } tree_t* initTree(){ tree_t* pTree = NULL; pTree = (tree_t*)malloc(sizeof(tree_t)); if(pTree == NULL){ printf("malloc error\n"); return NULL; } pTree->pRootNode = NULL; return pTree; } node_t* initNode(int value){ node_t* pNode = NULL; pNode = (node_t*)malloc(sizeof(node_t)); if(pNode == NULL){ printf("malloc error\n"); return NULL; } pNode->value = value; pNode->pLeftNode = NULL; pNode->pRightNode = NULL; return pNode; } node_t* insertNode(node_t* pNode, int value){ if(pNode == NULL){ return initNode(value); } if(value == pNode->value){ printf("already registered\n"); }else if(value < pNode->value){ pNode->pLeftNode = insertNode(pNode->pLeftNode, value); }else{ pNode->pRightNode = insertNode(pNode->pRightNode, value); } return pNode; } int insertNodeInTree(tree_t* pTree, int value){ node_t* pNode = NULL; if(pTree == NULL){ printf("arg chk error"); return -1; } pTree->pRootNode = insertNode(pTree->pRootNode, value); printfTree(pTree); return 0; } void freeNode(node_t* pNode){ if(pNode == NULL){ return; } freeNode(pNode->pLeftNode); freeNode(pNode->pRightNode); free(pNode); return; } int freeNodeInTree(tree_t* pTree){ if(pTree == NULL){ printf("arg chk error"); return -1; } freeNode(pTree->pRootNode); pTree->pRootNode = NULL; printfTree(pTree); return 0; } int printfMaxAndLevel(tree_t* pTree){ node_t* pNode = NULL; int level = 1; if(pTree == NULL){ printf("arg chk error"); return -1; } if(pTree->pRootNode == NULL){ printf("No node\n"); return -1; } pNode = pTree->pRootNode; while(pNode->pRightNode != NULL){ pNode = pNode->pRightNode; level++; } printf("max=%d level=%d\n", pNode->value, level); return -1; } int printfMinAndLevel(tree_t* pTree){ node_t* pNode = NULL; int level = 1; if(pTree == NULL){ printf("arg chk error"); return -1; } if(pTree->pRootNode == NULL){ printf("No node\n"); return -1; } pNode = pTree->pRootNode; while(pNode->pLeftNode != NULL){ pNode = pNode->pLeftNode; level++; } printf("min=%d level=%d\n", pNode->value, level); return -1; } int findNode(node_t* pNode, int value){ if(pNode == NULL){ return -1; } if(value == pNode->value){ return 0; }else if(value < pNode->value){ return findNode(pNode->pLeftNode, value); }else{ return findNode(pNode->pRightNode, value); } } int findNodeInTree(tree_t* pTree, int value){ if(pTree == NULL){ printf("arg chk error"); return -1; } if(findNode(pTree->pRootNode, value) == 0){ printf("existed\n"); }else{ printf("Not existed\n"); } return 0; } int main(){ tree_t* pTree = NULL; pTree = initTree(); insertNodeInTree(pTree, 2); insertNodeInTree(pTree, 3); insertNodeInTree(pTree, 1); insertNodeInTree(pTree, 6); insertNodeInTree(pTree, 5); insertNodeInTree(pTree, 5); printfMinAndLevel(pTree); printfMaxAndLevel(pTree); findNodeInTree(pTree, -1); findNodeInTree(pTree, 6); freeNodeInTree(pTree); return 0; }
下記が実行結果になります。
$ gcc -o sample sample.c $ ./sample Root 2 Left No node Right No node Root 2 Left No node Right 3 Left No node Right No node Root 2 Left 1 Left No node Right No node Right 3 Left No node Right No node Root 2 Left 1 Left No node Right No node Right 3 Left No node Right 6 Left No node Right No node Root 2 Left 1 Left No node Right No node Right 3 Left No node Right 6 Left 5 Left No node Right No node Right No node already registered Root 2 Left 1 Left No node Right No node Right 3 Left No node Right 6 Left 5 Left No node Right No node Right No node min=1 level=2 max=6 level=3 Not existed existed Root No node
スポンサーリンク