マルチフォークツリーの設計、作成、階層優先ループ、深さ優先ループ
18335 ワード
参照先:http://www.cnblogs.com/unixfy/p/3486179.html
ユーザのマルチフォークツリーデータは1つのファイルに格納され、aA 4 g cC z bBbB z 2 f i g 1 d 3 x e jの各行の最初の要素は1つのノードを指定し、2番目の要素はそのノードにいくつかのサブノードがあり、その後にいくつかのサブノードが付いていることを示す.
/*アルゴリズム1:階層優先マルチツリー(キュー)機能:マルチツリー内のノードをツリーの深さ(深さが大きいから小さい)で出力するため、スタック*/
/*アルゴリズム2:深度優先マルチフォーク(再帰)機能:ノードからリーフノードへのパス上のノード名のアルファベット数が最大のパスを見つける*/
実装:スタックのデータ構造;キューのデータ構造;マルチフォークツリーのデータ構造、マルチフォークツリーの作成、階層優先ループ(BFS)、深度優先ループ(DFS<再帰>)
まとめ:1.プログラム中(tmp=(char*)util_malloc((strlen(str)+strlen(head->name)*sizeof(char));//申請スペース、注意:ここのスペースは+1が必要で、tmp文字列の末尾の'0'を格納し、そうでなければ、裏面free(tmp)エラーを引き起こす)ここで注意2.freeは空のポインタ(p=NULL、free(p);)を解放することができるこれもなぜpのメモリを解放したのか、p=NULL(p=malloc(sizeof(...)、free(p)、p=NULL)と続く.これは主にp 3.mallocを再び解放した後に必ず手動でfreeを落とすことを避け、一般空間は少し大きく申請する
ユーザのマルチフォークツリーデータは1つのファイルに格納され、aA 4 g cC z bBbB z 2 f i g 1 d 3 x e jの各行の最初の要素は1つのノードを指定し、2番目の要素はそのノードにいくつかのサブノードがあり、その後にいくつかのサブノードが付いていることを示す.
/*アルゴリズム1:階層優先マルチツリー(キュー)機能:マルチツリー内のノードをツリーの深さ(深さが大きいから小さい)で出力するため、スタック*/
/*アルゴリズム2:深度優先マルチフォーク(再帰)機能:ノードからリーフノードへのパス上のノード名のアルファベット数が最大のパスを見つける*/
実装:スタックのデータ構造;キューのデータ構造;マルチフォークツリーのデータ構造、マルチフォークツリーの作成、階層優先ループ(BFS)、深度優先ループ(DFS<再帰>)
#include
#include
#include
#define MAX 100+1 //
//
typedef struct node_t{
char *name; //
int n_children; //
int level; //
struct node_t **children;// , children , node_t , node_t
}NODE;//NODE node_t
/*
: , typedef struct (
, ,)
{
} ;// NODE, , stuct node_t a, NODE a;
*/
//
typedef struct stact_t{
NODE **array; //array , NODE* ( , )
int index;//
int size; //
}STACK; //
//
typedef struct queue_t{
NODE **array; //
int head;//
int tail; //
int num;//
int size; //
}QUEUE;
// , , , ,
// ( malloc )
void *util_malloc(int size)
{
void *ptr = malloc(size);
if (ptr == NULL)// ,
{
printf("Memory allocation failed!
");
exit(EXIT_FAILURE);
}
return ptr;
}
// fopen()
FILE *util_fopen(const char *name, const char *access)
{
FILE *fp = fopen(name, access);
if (fp == NULL)
{
printf("Open file %s failed
", name);
exit(EXIT_FAILURE);
}
return fp;
}
//
//
STACK *StackInit(int size)
{
STACK *tmp;
tmp = (STACK*)util_malloc(sizeof(STACK));// ( , 4 (32 ), , , , )
tmp->size = size;
tmp->index = 0;
tmp->array = (NODE**)util_malloc(size*sizeof(NODE*)); // void * NODE* NODE**( void , NODE* )
return tmp; //
}
// : 1, 0
int StackEmpty(STACK *sp)
{
if (sp->index <= 0 || sp == NULL)
return 1;
else return 0;
}
//
int Push(STACK *sp, NODE *data)
{
if (sp->index >= sp->size || sp == NULL)
{
return 1; //
}
else
{
sp->array[sp->index++] = data;
return 0;
}
}
//
int Pop(STACK *sp, NODE **data)
{
if (sp->index <= 0 || sp == NULL)
{
return 1;
}
else
{
*data = sp->array[--sp->index];
return 0;
}
}
//
void StackDestroy(STACK *sp)
{
free(sp->array);
free(sp);
}
//
//
QUEUE *QueueInit(int size)
{
QUEUE *tmp;
tmp = (QUEUE*)util_malloc(sizeof(QUEUE));
tmp->array = (NODE**)util_malloc(size*sizeof(NODE*));
tmp->size = size;
tmp->head = tmp->tail = tmp->num = 0;
return tmp;
}
// :1 ,0
int QueueEmpty(QUEUE *qp)
{
if (qp->num <= 0 || qp == NULL)
return 1;
else return 0;
}
//
int Enqueue(QUEUE *qp, NODE *data)
{
if (qp->num >= qp->size || qp == NULL)
return 1;//
else
{
qp->array[qp->tail] = data;
qp->tail = (qp->tail + 1) % (qp->size); //
++qp->num;
return 0;
}
}
//
int Dequeue(QUEUE *qp, NODE **data)
{
if (qp->num <= 0 || qp == NULL)
return 1;
else
{
*data = qp->array[qp->head];
qp->head = (qp->head + 1) % (qp->size); //
--qp->num;
return 0;
}
}
//
void QueueDestory(QUEUE *qp)
{
free(qp->array);
free(qp);
}
//
NODE *CreatNode()
{
NODE *q;
q = (NODE *)util_malloc(sizeof(NODE));
q->name = NULL;
q->level = -1;
q->n_children = 0;
q->children = NULL;
return q;
}
//
NODE *SearchNode(const char *name, NODE *head)
{
NODE *tmp = NULL;
int i;
if (head != NULL)
{
if (strcmp(name, head->name) == 0)
tmp = head;
else
{
for (i = 0; i < head->n_children&&tmp==NULL; i++)
{
tmp = SearchNode(name, head->children[i]);// , tmp ,
}
}
}
return tmp;
}
// ,
void ReadFile(NODE **head, const char *filename)
{
NODE *tmp = NULL;
int i = 0, n = 0;
char name[MAX], child[MAX];
FILE *fp;
fp = util_fopen(filename, "r");
while (fscanf(fp, "%s %d", name, &n) != EOF)
{
if (*head == NULL)
{
tmp = *head = CreatNode();// ,
tmp->name = _strdup(name);// ,strdup , strcpy , , strdup , free ;
}
else
{
tmp = SearchNode(name, *head);// name , , name
}
tmp->n_children = n;
tmp->children = (NODE**)util_malloc(n*sizeof(NODE*));
if (tmp->children == NULL)
{
fprintf(stderr, "Dynamic allocation error !
");
exit(EXIT_FAILURE);
}
// , ,
for (i = 0; i < n; i++)
{
fscanf(fp, "%s", child);
tmp->children[i] = CreatNode();//
tmp->children[i]->name = _strdup(child);
}
}
fclose(fp);
}
/*
1: ( )
: ( ) ,
*/
void Bfs_Tree(NODE *head)
{
NODE *p = NULL;
QUEUE *q = NULL;//
STACK *s = NULL;//
int i = 0;
q = QueueInit(100);// 100
s = StackInit(100);// 100
head->level = 0;// 0
Enqueue(q, head);//
// level
// ,
while (QueueEmpty(q) == 0)//
{
Dequeue(q, &p);//
for (i = 0; i < p->n_children; i++)
{
p->children[i]->level = p->level + 1; // : 1
Enqueue(q, p->children[i]);//
}
Push(s, p);// p ,
}
while (StackEmpty(s) == 0)
{
Pop(s, &p);
fprintf(stdout, "%d %s
", p->level, p->name);
}
//
QueueDestory(q);
StackDestroy(s);
}
/*
2: ( )
:
*/
void DFS_Tree(NODE *head, char *str,char **iBest)
{
int i = 0;
char *tmp = NULL;
if (head == NULL)
return;
tmp = (char*)util_malloc((strlen(str) + strlen(head->name)+1)*sizeof(char)); // , : +1, tmp '\0', , free(tmp)
sprintf(tmp, "%s%s", str, head->name); // 5 printf
if (head->n_children == 0)
{
if (*iBest == NULL || strlen(*iBest) < strlen(tmp))
{
free(*iBest); // , strdup ,
*iBest = _strdup(tmp);
}
}
for (i = 0; i < head->n_children; i++)
{
DFS_Tree(head->children[i], tmp,iBest);
}
free(tmp); //
}
// ( )
void Destoy_Tree(NODE *head)
{
int i;
if (head == NULL)
return;
else
{
for (i = 0; i < head->n_children; i++)
Destoy_Tree(head->children[i]);
free(head->name);// name strdup
free(head->children);//
free(head);
}
}
int main(int argc, char **argv)
{
NODE *head = NULL;
char *iBest = NULL;
if (argc != 2)
{
fprintf(stderr, "Lack of parameters!
");
exit(EXIT_FAILURE);
}
ReadFile(&head, argv[1]);
Bfs_Tree(head);
DFS_Tree(head, "", &iBest);
fprintf(stdout, "%s
", iBest);
free(iBest);
Destoy_Tree(head);
system("pause");
return 0;
}
まとめ:1.プログラム中(tmp=(char*)util_malloc((strlen(str)+strlen(head->name)*sizeof(char));//申請スペース、注意:ここのスペースは+1が必要で、tmp文字列の末尾の'0'を格納し、そうでなければ、裏面free(tmp)エラーを引き起こす)ここで注意2.freeは空のポインタ(p=NULL、free(p);)を解放することができるこれもなぜpのメモリを解放したのか、p=NULL(p=malloc(sizeof(...)、free(p)、p=NULL)と続く.これは主にp 3.mallocを再び解放した後に必ず手動でfreeを落とすことを避け、一般空間は少し大きく申請する