Деревья. Найти число листьев - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Помогите, пожалуйста! мне нужно найти число листьев на каждом уровне дерева. Я слышала, что это делается через рекурсию. А можно ли сделать без неё? Подскажите, пожалуйста, как. А ещё меня интересует, как потом можно будет вызвать эту функцию. Заранее спасибо

Решение задачи: «Деревья. Найти число листьев»

textual
Листинг программы
#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 создается двоичное дерево и вычисляются уровни узлов. Код завершается освобождением памяти, выделенной под структуры данных.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

14   голосов , оценка 4.071 из 5
Похожие ответы