Форум программистов, компьютерный форум CyberForum.ru

Сохранение и чтение бин. дерева - C++

Восстановить пароль Регистрация
 
vaselo
19 / 19 / 1
Регистрация: 17.10.2010
Сообщений: 247
10.04.2011, 21:24     Сохранение и чтение бин. дерева #1
написал функцию хранения дерева
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int save(node* p)
{
    char fname [80];
    if (p==0) {cout<<"Пусто";Sleep(500);return -1;}
    cout<<"Введите имя (путь) к файлу: \n";
    cin>>fname;
    ofstream ofs(fname);
    do
        {
        save(p->l);
        ofs<<p->info<<endl<<p->c<<endl;  // инфо - поле информации, с - счетчик вхождений элемента
        save(p->r);
        }while(p);
    ofs.close();
    return 0;
столкнулся с тем, что при рекурсии просит ввести имя файла. если открываю файл в одной ф-ции, а рекурсивная - другая, то поток не может сохранять - не компилится. подскажите, как обойти эту проблему? как передать из текст. файла информацию для считывания обратно в ОП? надеюсь только на вашу помощь! вот ф-ция построения дерева:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
node *tree(node *p, int w)
{
  if (p == NULL)
  {
    p = new node;
    p->info = w;
    p->l=NULL;
    p->r=NULL;
    p->c=1;
  }
  else if (w==p->info) // Если такая информация встречалась,
  {
    p->c+=1; // то счетчик количества увеличивается на 1
  }
  else if (w<p->info) // eсли меньше, то идем по левому указателю
  {
    p->l=tree(p->l,w);
  }
  else
  {
    p->r=tree(p->r,w); // иначе по правому
  }
 
  return p; 
}
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
11.04.2011, 07:54     Сохранение и чтение бин. дерева #2
подскажите, как обойти эту проблему?
Убрать запрос имени фаила и его открытие из рекурсивной функции, передавать выводной поток ей в качестве параметра.
как передать из текст. файла информацию для считывания обратно в ОП?
Если прочитанное дерево не обязано быть идентичным сохраненному, то просто читать элементы по одному и строить новое дерево из этих элементов.
vaselo
19 / 19 / 1
Регистрация: 17.10.2010
Сообщений: 247
11.04.2011, 09:13  [ТС]     Сохранение и чтение бин. дерева #3
спасибо, а считанное должно быть идентичным, вот в чем сложность
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
11.04.2011, 09:30     Сохранение и чтение бин. дерева #4
Цитата Сообщение от vaselo Посмотреть сообщение
спасибо, а считанное должно быть идентичным, вот в чем сложность
в этом случае способ обхода дерева при сохранения должен соответствовать способу построения. Здесь вопрос ближе к реализации и свойствам конкретного алгоритма.

П.С.:
уверены? (просто способ построения предложенный Вами во втором блоке кода говорит скорее об обратном).
vaselo
19 / 19 / 1
Регистрация: 17.10.2010
Сообщений: 247
11.04.2011, 09:37  [ТС]     Сохранение и чтение бин. дерева #5
Цитата Сообщение от Vladimir. Посмотреть сообщение
П.С.:
уверены? (просто способ построения предложенный Вами во втором блоке кода говорит скорее об обратном).
там я получаю отсортированное дерево. где одинаковые элементы не повторяются, а увеличивают счетчик С. вот пусть будет записано
1
2//-шт
4
5//-штук как рекурсивно обходить, считывая строки и сохранять их так же упорядоченно?
Vladimir.
155 / 155 / 10
Регистрация: 24.11.2009
Сообщений: 375
11.04.2011, 10:05     Сохранение и чтение бин. дерева #6
Вы строите упорядоченное двоичное дерево, ключами выступают сами значения, после сейв/лоад Вам нужно получить опять же упорядоченное двоичное дерево. Предлагается просто обойти всё дерево любым способом (прямой обход, например) и писать значения в фаил, если где-либо счетчик отличен от 1, то просто записывать значения в фаил несколько раз. При чтении из фаила, Вы просто берёте очередное значение и добавляете его в дерево.

К чему были все эти вопросы ранее:
Можно привести примеры использования деревьев в которых полезными данными будут не только значения в хранимые в узлах, но и само расположение узлов. Ваша задача к таким не относится.

например: реализация алгоритма Хаффмана, в которой для построения кодовой последовательности используется бинарное дерево. На одних и тех же данных возможно получение различных деревьев и, следовательно, различных кодов.
vaselo
19 / 19 / 1
Регистрация: 17.10.2010
Сообщений: 247
11.04.2011, 17:05  [ТС]     Сохранение и чтение бин. дерева #7
перенес рекурсию, но теперь компилятор ругается непонятными выражениями
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <fstream>
using namespace std;
#include <conio.h>
 
struct node // Структура узла
{
  int info;      // Информационное поле
  int c;         // Счетчик
  node *l,*r; // Левый и правый указатели
};
 
// -------Функция построения дерева---------
 
 
node *tree(node *p, int w)
{
  if (p == NULL)
  {
    p = new node;
    p->info = w;
    p->l=NULL;
    p->r=NULL;
    p->c=1;
  }
  else if (w==p->info) // Если такая информация встречалась,
  {
    p->c+=1; // то счетчик количества увеличивается на 1
  }
  else if (w<p->info) // eсли меньше, то идем по левому указателю
  {
    p->l=tree(p->l,w);
  }
  else
  {
    p->r=tree(p->r,w); // иначе по правому
  }
 
  return p; 
}
 
//--------- Функция обхода дерева -------------
 
void treeprint(node *p)
{
  if (p != NULL)
  {
    treeprint(p->l); // по левому указателю
    cout<<p->c<<" "<<p->info<<endl;
    treeprint(p->r); // по правому указателю
  }
}
void PrintTree(node* p,int l)
{
           if(p!=NULL)
           {
                PrintTree(p->l,l+1);
                for(int i=0;i<l;i++){cout<<"__";}
                cout<<p->info<<"("<<p->c<<")\n";
                PrintTree(p->r,l+1);
           }
        }
int save(node* p,ofstream ofs)
{
    do
        {
        save(p->l,ofs);
        ofs<<p->info<<endl<<p->c<<endl;
        save(p->r,ofs);
        }while(p);
    return 0;
}
 
void main()
{
  node *root; // Рабочий указатель на корень дерева
  int w,l=0;
  root=NULL; //Дерево пустое
  scanf("%d", &w);
 
  while (w!=0)
  {
    root=tree(root, w);
    scanf("%d", &w);
  }
 
  PrintTree(root,l);
  system("pause");
 
 
 
  char fname [80];
    if (root==0) {cout<<"Пусто";Sleep(500);return;}
    cout<<"Введите имя (путь) к файлу: \n";
    cin>>fname;
    ofstream ofs(fname);
 
 
 
 
  save(root, ofs);
}
 
 
 Сообщение диагностики возникло в созданной компилятором функции "std::basic_ofstream<_Elem,_Traits>::basic_ofstream(const std::basic_ofstream<_Elem,_Traits> &)"
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.04.2011, 00:30     Сохранение и чтение бин. дерева
Еще ссылки по теме:

Сохранение класса в файл и его чтение C++
C++ Чтение дерева из файла
C++ Сохранение и чтение структуры из файла (crash программы)

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
vaselo
19 / 19 / 1
Регистрация: 17.10.2010
Сообщений: 247
14.04.2011, 00:30  [ТС]     Сохранение и чтение бин. дерева #8
ф-цией сейв пишу в файл цифры из узла дерева, столько, сколько записано в поле "с". теперь нужно считать в дин. память из файла:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void save(node* root)
{
    char fname [80];
    cout<<"Введите имя (путь) к файлу: \n";
    cin>>fname;
    ofstream ofs(fname);
    do
        {
            for(int i=0;i<root->c;i++)
                ofs<<root->info<<endl;
            if(root->l)root=root->l;
            else root=root->r;
        }while(root);
    ofs.close();
}
void read(node* &root)
{
    int c;// переменная, которую передаю в ф-цию построения дерева
    ifstream dataIn;
    char fname [30];
    cout<<"Введите имя (путь) к файлу: \n";
    cin>>fname;
    dataIn.open(fname);
            if(dataIn.is_open())
            {      
                while(dataIn.good())
                    {   
                                                       dataIn.read(c,36);// поочередно нужно читать циферку(в файле цифра записывается каждый раз с новой строки) вот тут и возникла трудность считывания.... помогите хоть советом
                    //нужно просто считать в "с" число из файла, вызвать ф-цию tree(node);      
                    }
                    system("pause");
                    dataIn.close();
            }
            else cout<<"Не удалось открыть файл для чтения\n";Sleep(500);
}
Yandex
Объявления
14.04.2011, 00:30     Сохранение и чтение бин. дерева
Ответ Создать тему
Опции темы

Текущее время: 19:15. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru