Функция построения дерева поиска из файла - C (СИ)
Формулировка задачи:
Cколько не пытаюсь - не получается
#include <stdio.h>
#include <stdlib.h>
typedef struct NODE NODE;
typedef struct NODE *TREE;
struct NODE
{
int key;
int count;
struct NODE *left;
struct NODE *right;
}node;
TREE build_tree(int n, int tkey)
{
TREE root = NULL;
int nr, nl, i;
if(n == 1)
root = NULL;
for(i = 1; i <= n; i++)
{
nl = n - 1;
nr = n - nl - 1;
root = (TREE)malloc(sizeof(node));
root->key = tkey;
root->left = build_tree(nl, tkey + 1);
root->right = build_tree(nr, tkey + 1);
}
return root;
}
void print_tree(TREE tr, int h)
{
int i;
if(tr != NULL)
{
print_tree(tr->left, h + 1);
for(i = 0; i < h; i++)
printf(" ");
printf("%d\n", tr->key);
print_tree(tr->right, h + 1);
}
}
int main()
{
TREE tree;
FILE *F;
int a;
if ((F=fopen("1.txt","r"))==NULL)
{
printf("fail F otkrit ne udalos!\n");
exit(1);
}
while ((fscanf(F, "%d", &a)) == 1) {
if (a){
tree = build_tree(a, 1);
}
}
print_tree(tree, 0);
return 0;
}Решение задачи: «Функция построения дерева поиска из файла»
textual
Листинг программы
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define max(a, b) ( (a) > (b) ? (a) : (b) )
typedef struct NODE {
int key;
int count;
int height;
struct NODE * left;
struct NODE * right;
} node_t;
node_t * node_new(const int key) {
node_t * node = malloc(sizeof(node_t));
if ( ! node )
return NULL;
node->key = key;
node->count = 1;
node->height = 1;
node->left = NULL;
node->right = NULL;
return node;
}
void kill_tree(node_t * tree) {
if ( tree ) {
kill_tree(tree->left);
kill_tree(tree->right);
free(tree);
}
}
int tree_height(node_t * tree) {
return ( tree ) ? tree->height : 0;
}
int tree_bf(node_t * tree) {
return tree_height(tree->right) - tree_height(tree->left);
}
void tree_fixheight(node_t * tree) {
int lh, rh;
assert( tree );
lh = tree_height(tree->left);
rh = tree_height(tree->right);
tree->height = max(lh, rh) + 1;
}
node_t * rotate_right(node_t * n) {
node_t * l;
assert( n );
l = n->left;
assert( l );
n->left = l->right;
l->right = n;
tree_fixheight(n);
tree_fixheight(l);
return l;
}
node_t * rotate_left(node_t * n) {
node_t * r;
assert( n );
r = n->right;
assert( r );
n->right = r->left;
r->left = n;
tree_fixheight(n);
tree_fixheight(r);
return r;
}
node_t * tree_balance(node_t * tree) {
assert( tree );
tree_fixheight(tree);
switch ( tree_bf(tree) ) {
case 2 :
if ( tree_bf(tree->right) < 0 )
tree->right = rotate_right(tree->right);
return rotate_left(tree);
case -2 :
if ( tree_bf(tree->left) > 0 )
tree->left = rotate_left(tree->left);
return rotate_right(tree);
default:
return tree;
}
}
node_t * tree_insert(node_t * tree, const int key) {
if ( ! tree )
return node_new(key);
else if ( tree->key == key ) {
tree->count += 1;
return tree;
}
else if ( tree->key > key )
tree->left = tree_insert(tree->left, key);
else
tree->right = tree_insert(tree->right, key);
return tree_balance(tree);
}
node_t * tree_from_file(const char * fileName) {
FILE * f;
node_t * tree = NULL;
int n;
if ( ! ( f = fopen(fileName, "r") ) )
return NULL;
while ( fscanf(f, "%d", &n) == 1 )
tree = tree_insert(tree, n);
fclose(f);
return tree;
}
void tree_dump(node_t * tree, FILE * f) {
if ( tree ) {
int i;
tree_dump(tree->left, f);
for ( i = 0; i < tree->count; ++i )
fprintf(f, "%d\n", tree->key);
tree_dump(tree->right, f);
}
}
int tree_to_file(node_t * tree, const char * fileName) {
FILE * f = fopen(fileName, "w");
if ( ! f )
return -1;
tree_dump(tree, f);
return ( ferror(f) || fclose(f) );
}
#define INPUT_FILE_NAME "in.txt"
#define OUTPUT_FILE_NAME "out.txt"
int main(void) {
node_t * tree = tree_from_file(INPUT_FILE_NAME);
int ret = tree_to_file(tree, OUTPUT_FILE_NAME);
kill_tree(tree);
return ret;
}
Объяснение кода листинга программы
- Функция
node_newсоздает новый узел дерева поиска с заданным ключом и инициализирует его значениями счетчика и высоты. - Функция
kill_treeрекурсивно освобождает память, выделенную под узлы дерева, начиная с указанного узла. - Функция
tree_heightвозвращает высоту поддерева, корнем которого является указанный узел. - Функция
tree_bfвычисляет разницу в высотах поддеревьев, корнями которых являются левый и правый узлы указанного узла. - Функция
tree_fixheightустанавливает высоту указанного узла равной максимальной высоте поддерева, корнями которого являются его левый и правый узлы. - Функция
rotate_rightвыполняет поворот узла и его потомков вправо. - Функция
rotate_leftвыполняет поворот узла и его потомков влево. - Функция
tree_balanceвыполняет необходимые повороты для балансировки указанного узла. - Функция
tree_insertрекурсивно добавляет новый узел с заданным ключом в указанное поддерево. - Функция
tree_from_fileсоздает дерево поиска из файла, содержащего набор целых чисел. - Функция
tree_dumpрекурсивно выводит содержимое указанного поддерева в файл. - Функция
tree_to_fileзаписывает дерево поиска в файл, преобразуя его в последовательность целых чисел. - В функции
mainсоздается дерево поиска из файлаin.txt, а затем оно записывается в файлout.txt.