1,普通树有深度优先和广度优先两种遍历方式。深度优先还有先序遍历和后续遍历两种子方法,普通树没有中序遍历方法。
2,深度优先的的特点是左子树永远优先于右子树被先遍历到。
3, 深度优先的先序遍历的特点是,不仅左子树优先于右子树被先遍历,而且是上面节点比下面节点优先遍历。
4,广度优先是上层节点比下层节点优先遍历,左面节点比右面节点先遍历。
5,从2,3条见上看,可以组织一种数学描述方式,而这种描述方式可以被四描述出来。
6,深度优先的后序遍历,树中的下面节点比树中的上面节点先遍历到,因此,可以利用这一特点对树上的资源释放。
#include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<errno.h>
const int TREE[] = { //
1, //Root has tree children
1, //First child has one child
0, //It is leaf
-1, //Terminal
1, //Second child has one child
0, //It is the second child's first child
1, //It is the second child's second child
0, //It is the second child's second child's child
-1, //Terminal
-1, //Terminal
0, //The third child is leaf
-1 //Terminal
};
struct my_list_body {
void *value;
struct my_list_body *next;
};
struct my_list{
struct my_list_body *head;
struct my_list_body *tail;
};
void my_list_append(struct my_list *list, void *value) {
struct my_list_body *new_node = malloc(sizeof(struct my_list_body));
new_node->value = value;
new_node->next = NULL;
if(list->head == NULL) {
list->head = new_node;
list->tail = new_node;
}
else {
list->tail->next = new_node;
list->tail = new_node;
}
}
void *my_list_pop(struct my_list *list) {
struct my_list_body *result = list->head;
if (!result) return NULL;
list->head = result->next;
return result;
}
struct my_tree {
char key;
struct my_list *children;
};
static int level = 0;
void print_node() {
int i = 0;
for(;i < level; i++) printf("/t");
printf("#/n");
}
int _init_my_tree(struct my_tree *tree, const int **expr) {
static int err = 0;
if(err) return -1;
int indicator = **expr;
(*expr)++;
if((indicator != 0) && (indicator != 1) && (indicator != -1)){
err = 1;
return -1;
}
struct my_list *brothers = tree->children;
if (indicator == -1) {
if (!brothers) {
err = 1;
return -1;
}
level --;
return 0;
}
else {
if (!brothers) {
brothers = malloc(sizeof(struct my_list));
memset(brothers, 0, sizeof(struct my_list));
tree->children = brothers;
}
struct my_tree *new_tree = malloc(sizeof (struct my_tree));
new_tree->children = NULL;
my_list_append(brothers, new_tree);
print_node();
if (indicator == 1) {
level++;
if (_init_my_tree(new_tree, expr) == -1)
return -1;
}
return _init_my_tree(tree, expr);
}
}
struct my_tree *init_my_tree(const int expr[]){
int indicator = *expr;
if((indicator != 0) && (indicator != 1)) return;
struct my_tree *tree = malloc(sizeof (struct my_tree));
tree->children = NULL;
print_node();
level++;
expr++;
if (_init_my_tree(tree, &expr) == -1)
{
free(tree);
tree = NULL;
}
return tree;
}
void do_on_node(struct my_tree *node, int *seq_id, int level_num) {
int i =0;
static int node_id = 0;
for(;i < level_num; i++) {
printf("/t");
}
node->key = 'A' + node_id++;
printf("%c:{", node->key);
for(i = 0; i <= level_num; i++) {
printf("%d,", seq_id[i]);
}
printf("/b}/n");
}
void _deepfirst_traversal(struct my_tree *tree, int seq_id[], int level_number){
do_on_node(tree, seq_id, level_number);
struct my_list *children = tree->children;
if (children == NULL) return;
int seq_id_len = level_number + 1;
int sub_seq_id_len = seq_id_len + 1;
int sub_seq_id[sub_seq_id_len];
memcpy(sub_seq_id, seq_id, sizeof(int) * seq_id_len);
struct my_list_body *body = children->head;
int i = 0;
for(;body != NULL; body = body->next, i++) {
sub_seq_id[sub_seq_id_len - 1] = i;
struct my_tree *tree_node = (struct my_tree*)body->value;
_deepfirst_traversal(tree_node, sub_seq_id, ++level_number);
level_number --;
}
}
void deepfirst_traversal(struct my_tree *tree) {
if (!tree) return;
int seq_id[] = {0};
_deepfirst_traversal(tree, seq_id, 0);
}
void _crash_tree(struct my_tree *tree){
struct my_list *children = tree->children;
if (children == NULL) return;
struct my_list_body *node = children->head;
while(node != NULL) {
struct my_tree *tree_node = (struct my_tree*)node->value;
_crash_tree(tree_node);
printf("free node (%c), ", tree_node->key);
if(tree_node->children) free(tree_node->children);
tree_node->children = NULL;
free(tree_node);
tree_node = NULL;
node->value = NULL;
struct my_list_body *tmp_node = node;
node = node->next;
free(tmp_node);
}
}
void crash_tree(struct my_tree *tree){
_crash_tree(tree);
printf("free node (%c) /n", tree->key);
if(tree->children) free(tree->children);
tree->children = NULL;
free(tree);
tree = NULL;
}
struct level_node {
struct my_tree *tree_node;
int *value;
int level_num;
};
struct level_node *make_level_node(struct my_tree *tree, int *seq_id, int level_num) {
struct level_node *result = malloc(sizeof(struct level_node));
result->tree_node = tree;
result->value = seq_id;
result->level_num = level_num;
return result;
}
struct my_list *widefirst_traversal(struct my_tree *tree) {
struct my_list *pip = malloc(sizeof(struct my_list));
struct my_list *result = malloc(sizeof(struct my_list));
if (tree->children) {
int *seq_id = malloc(sizeof(int));
*seq_id = 0;
struct level_node * root_lv_node = make_level_node(tree, seq_id, 0);
my_list_append(result, root_lv_node);
my_list_append(pip, root_lv_node);
}
while(pip->head){
struct my_list_body *element = my_list_pop(pip);
struct level_node *lvnode = (struct level_node *)element->value;
struct my_tree *tree = lvnode->tree_node;
int level_num = lvnode->level_num;
int *seq_id = lvnode->value;
int seq_id_len = (level_num + 1) * sizeof(int);
struct my_list *children = tree->children;
struct my_list_body *node = children->head;
int i = 0;
for(;node; node=node->next, i++){
struct my_tree *sub_tree = (struct my_tree*)node->value;
int sub_level_num = level_num + 1;
int sub_seq_id_len = seq_id_len + sizeof(int);
int *sub_seq_id = malloc(sub_seq_id_len);
memcpy(sub_seq_id, seq_id, seq_id_len);
sub_seq_id[sub_level_num] = i;
struct level_node *sub_lv_node = make_level_node(sub_tree, sub_seq_id, sub_level_num);
if(sub_tree->children) {
my_list_append(pip, sub_lv_node);
}
my_list_append(result, sub_lv_node);
}
}
free(pip);
return result;
}
void print_level_list(struct my_list *list) {
struct my_list_body *body = list->head;
int tmp_level_num = 0;
for(; body != NULL; body = body->next) {
struct level_node *lvnode = body->value;
struct my_tree *treenode = lvnode->tree_node;
char c = treenode->key;
int *seq_id = lvnode->value;
int level_num = lvnode->level_num;
if(level_num != tmp_level_num) {
tmp_level_num = level_num;
printf("/n===========================================/n");
}
printf("%c:{", c);
int i = 0;
for(;i <= level_num; i++) {
printf("%d,",seq_id[i]);
}
printf("/b} ");
}
printf("/n");
}
int main(int argc, char *argv[]){
printf(
"/nInput epression mode likes follow: /n"
"1, //Root has tree children /n"
" 1, //First child has one child /n"
" 0, //It is leaf /n"
" -1, //terminate /n"
" 1, //Second child has one child /n"
" 0, //It is the second child's first child /n"
" 1, //It is the second child's second child /n"
" 0, //It is the second child's second child's child /n"
" -1, //Terminate /n"
" -1, //Terminate /n"
" 0, //The third child is leaf /n"
"-1 //Terminal. /n"
);
printf("/nFollow is the tree diagram witch initialized by the above expression./n");
struct my_tree *tree = init_my_tree(TREE);
printf("/nThe result of deep-first and previously order traversals./n");
deepfirst_traversal(tree);
printf("/nThe result of wide-first traversals./n");
struct my_list *wdt_ret = widefirst_traversal(tree);
print_level_list(wdt_ret);
printf("/nTher serial order of release the tree./n");
crash_tree(tree);
printf("/n");
return 0;
}
程序输出:
Input epression mode likes follow:
1, //Root has tree children
1, //First child has one child
0, //It is leaf
-1, //terminate
1, //Second child has one child
0, //It is the second child's first child
1, //It is the second child's second child
0, //It is the second child's second child's child
-1, //Terminate
-1, //Terminate
0, //The third child is leaf
-1 //Terminal.
Follow is the tree diagram witch initialized by the above expression.
#
#
#
#
#
#
#
#
The result of deep-first and previously order traversals.
A:{0}
B:{0,0}
C:{0,0,0}
D:{0,1}
E:{0,1,0}
F:{0,1,1}
G:{0,1,1,0}
H:{0,2}
The result of wide-first traversals.
A:{0}
===========================================
B:{0,0} D:{0,1} H:{0,2}
===========================================
C:{0,0,0} E:{0,1,0} F:{0,1,1}
===========================================
G:{0,1,1,0}
Ther serial order of release the tree.
free node (C), free node (B), free node (E), free node (G), free node (F), free node (D), free node (H), free node (A)