Деревья. Найти число листьев - C (СИ)
Формулировка задачи:
Решение задачи: «Деревья. Найти число листьев»
#include <stdio.h> #include <stdlib.h> #include <assert.h> typedef struct LEVELCOUNTERNODE { int level; int count; struct LEVELCOUNTERNODE * prev; struct LEVELCOUNTERNODE * next; } counternode_t; counternode_t * counternode_new(const int level) { counternode_t * node = malloc(sizeof(counternode_t)); if ( ! node ) return NULL; node->level = level; node->count = 1; node->prev = NULL; node->next = NULL; return node; } typedef struct LEVELCOUNTERSLIST { counternode_t * first; } counterslist_t; counterslist_t * counterslist_new(void) { counterslist_t * list = malloc(sizeof(counterslist_t)); if ( ! list ) return NULL; list->first = NULL; return list; } void counterslist_free(counterslist_t * list ) { while ( list->first ) { counternode_t * next = list->first->next; free(list->first); list->first = next; } free(list); } void counterslist_inc_counter(counterslist_t * list, const int level) { counternode_t * node = counternode_new(level); assert ( node ); if ( list->first == NULL ) list->first = node; else if ( list->first->level > node->level ) { node->next = list->first; list->first->prev = node; list->first = node; } else { counternode_t * current = list->first; int found = 0; while ( ! found ) { if ( current->level == node->level ) { current->count += 1; free(node); found = 1; } else if ( current->level > node->level ) { node->prev = current->prev; current->prev->next = node; current->prev = node; node->next = current; found = 1; } else if ( current->next == NULL ) { current->next = node; node->prev = current; found = 1; } else current = current->next; } } } void counterslist_dump(counterslist_t * list) { counternode_t * node = list->first; printf("Level Count\n-----------\n"); while ( node ) { printf("%5d %5d\n", node->level, node->count); node = node->next; } } typedef struct INTTREENODE { int value; struct INTTREENODE * left; struct INTTREENODE * right; } treenode_t; treenode_t * treenode_new(const int value) { treenode_t * node = malloc(sizeof(treenode_t)); if ( ! node ) return NULL; node->value = value; node->left = NULL; node->right = NULL; return node; } void treenode_free(treenode_t ** pNode) { assert ( pNode ); if ( *pNode ) { treenode_free(&((*pNode)->left)); treenode_free(&((*pNode)->right)); free(*pNode); *pNode = NULL; } } int treenode_add(treenode_t ** pNode, const int value) { assert ( pNode ); if ( ! *pNode ) return ( *pNode = treenode_new(value) ) ? 0 : -1; else if ( (*pNode)->value > value ) return treenode_add(&((*pNode)->left), value); else if ( (*pNode)->value < value ) return treenode_add(&((*pNode)->right), value); else return 0; } void treenode_dump_ascendant(treenode_t * node) { if ( node ) { treenode_dump_ascendant(node->left); printf("%d ", node->value); treenode_dump_ascendant(node->right); } } void treenode_count(treenode_t * node, int level, counterslist_t * counters) { if ( node ) { counterslist_inc_counter(counters, level); treenode_count(node->left, level + 1, counters); treenode_count(node->right, level + 1, counters); } } typedef struct INTTREE { treenode_t * root; } inttree_t; inttree_t * inttree_new(void) { inttree_t * tree = malloc(sizeof(inttree_t)); if ( ! tree ) return NULL; tree->root = NULL; return tree; } void inttree_free(inttree_t * tree) { assert ( tree ); if ( tree->root ) treenode_free(&(tree->root)); free(tree); } void inttree_push(inttree_t * tree, const int value) { assert ( treenode_add(&(tree->root), value) == 0 ); } counterslist_t * inttree_levels_info(inttree_t * tree) { counterslist_t * counters = counterslist_new(); if ( ! counters ) return NULL; treenode_count(tree->root, 0, counters); return counters; } void inttree_dump(inttree_t * tree) { treenode_dump_ascendant(tree->root); } int main(void) { inttree_t * tree; counterslist_t * counters; assert ( tree = inttree_new() ); inttree_push(tree, 13); inttree_push(tree, 7); inttree_push(tree, 25); inttree_push(tree, 5); inttree_push(tree, 10); inttree_push(tree, 19); inttree_push(tree, 30); inttree_push(tree, 6); inttree_push(tree, 8); inttree_push(tree, 12); printf("Tree:\n"); inttree_dump(tree); printf("\n"); assert ( counters = inttree_levels_info(tree) ); printf("Levels info:\n"); counterslist_dump(counters); inttree_free(tree); counterslist_free(counters); return 0; }
Объяснение кода листинга программы
В данном коде реализован алгоритм подсчета количества узлов на каждом уровне двоичного дерева.
Сначала определены структуры данных для представления узлов и списка узлов.
typedef struct LEVELCOUNTERNODE {
int level;
int count;
struct LEVELCOUNTERNODE prev;
struct LEVELCOUNTERNODE next;
} counternode_t;
typedef struct LEVELCOUNTERSLIST {
counternode_t first;
} counterslist_t;
Затем определены функции для работы со списками узлов и двоичными деревьями.
counterslist_t counterslist_new(void) {
counterslist_t list = malloc(sizeof(counterslist_t));
if ( ! list )
return NULL;
list->first = NULL;
return list;
}
void counterslist_free(counterslist_t list ) {
while ( list->first ) {
counternode_t next = list->first->next;
free(list->first);
list->first = next;
}
free(list);
}
inttree_t inttree_new(void) {
inttree_t tree = malloc(sizeof(inttree_t));
if ( ! tree )
return NULL;
tree->root = NULL;
return tree;
}
void inttree_free(inttree_t tree) {
assert ( tree );
if ( tree->root )
treenode_free(&(tree->root));
free(tree);
}
counterslist_t inttree_levels_info(inttree_t tree) {
counterslist_t counters = counterslist_new();
if ( ! counters )
return NULL;
treenode_count(tree->root, 0, counters);
return counters;
}
Затем в функции main создается двоичное дерево и вычисляются уровни узлов.
int main(void) {
inttree_t tree;
counterslist_t * counters;
assert ( tree = inttree_new() );
inttree_push(tree, 13);
inttree_push(tree, 7);
inttree_push(tree, 25);
inttree_push(tree, 5);
inttree_push(tree, 10);
inttree_push(tree, 19);
inttree_push(tree, 30);
inttree_push(tree, 6);
inttree_push(tree, 8);
inttree_push(tree, 12);
printf(Tree:\n
);
inttree_dump(tree);
printf(\n
);
assert ( counters = inttree_levels_info(tree) );
printf(Levels info:\n
);
counterslist_dump(counters);
inttree_free(tree);
counterslist_free(counters);
return 0;
}
Код начинается с определения структур данных для представления узлов и списка узлов. Затем определены функции для работы со списками узлов и двоичными деревьями. В функции main создается двоичное дерево и вычисляются уровни узлов. Код завершается освобождением памяти, выделенной под структуры данных.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д