Нужен графический ввод/вывод
29.05.2019, 19:54. Показов 660. Ответов 0
Срочно нужна помощь в доработке курсового проекта!
Тема "Реализация операций над деревом Фибоначчи"
Программа в общих чертах готова, осталось доработать графический ввод/вывод через Canvas. Но не получается аддекватно его сделать.
Вот код основного файла:
| 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
| //---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <vector>
#include <fstream>
using namespace std;
#include "Main.h"
#include "ClassTree.h"
#include "MethodTree.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{ }
//---------------------------------------------------------------------------
//глобальные переменные
vector<int>XTree;
vector<int>YTree;
int X = 300, Y = 50;//, dX = 0, dY = 0;
unsigned int FibonacciSeries[20] = {0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181}; //ряд Фибоначчи
int sizeTree = 0; //размер дерева
int heightTree = 1; //высота дерева
vector<int> Save; //вектор сохранения и загрузки
Tree<int> Fibonacci; //Дерево
//Func_FibonacciSeries - расчёт F-числа Фибоначчи. F - положительное целое число
unsigned int Func_FibonacciSeries (unsigned int F)
{
unsigned int OldValue = 0;
unsigned int Value = 1;
unsigned int Hold;
if(F < 1) {return(0);}
for(int i = 1; i < F; i++)
{
Hold = Value;
Value+=OldValue;
OldValue = Hold;
}
return Value;
}
void __fastcall TForm1::FormActivate(TObject *Sender)
{
//sizeTree = (k>17)? Func_FibonacciSeries(k+2)-1 : FibonacciSeries[k+2]-1; //формула чисо вершин в дереве фибоначчи
//выше определение размера функцией, но портит создание начальное. Переделать или нет?
}
//---------------------------------------------------------------------------
//удаление
void __fastcall TForm1::DelBClick(TObject *Sender)
{
try {
int del;
if (!DelRB1->Checked)
del = StrToInt(KeyDelE->Text);
if (DelRB1->Checked)
{
Fibonacci.DelTree(Fibonacci.GetChange());
Timer1->Enabled = false;
SizeL->Caption = IntToStr(0);
MaxL->Caption = IntToStr(0);
MinL->Caption = IntToStr(0);
}
if (DelRB2->Checked)
Fibonacci.DelSubTree (Fibonacci.GetChange(), del, Fibonacci.GetChange());
if (DelRB3->Checked)
Fibonacci.DelNode (Fibonacci.GetChange(), del);
Memo1->Lines->Clear();
Memo1->Lines->Add("Fibonacci Tree");
Fibonacci.PrintTree (Fibonacci.GetPrint(),0);
}
catch (...) { MessageBox(0, L"Введите целое число!", L"Ошибка!", MB_OK); }
}
//---------------------------------------------------------------------------
//сохранение
void __fastcall TForm1::SaveBClick(TObject *Sender)
{
if (Form1->SaveDialog1->Execute())
{
Fibonacci.SetSave(Fibonacci.GetPrint());
ofstream file;
file.open(SaveDialog1->FileName.c_str(), ios::trunc);
file<<heightTree<<'/'<<endl;
for (int i = 0;i < sizeTree-1; i++)
{
file<<Save[i]<<'|';
}
file.close();
}
}
//---------------------------------------------------------------------------
//загрузка
void __fastcall TForm1::LoadBClick(TObject *Sender)
{
if (Form1->OpenDialog1->Execute())
{
if (FileExists(OpenDialog1->FileName))
{
Save.clear();
const int buff=10;
char line [buff];
ifstream file;
file.open(OpenDialog1->FileName.c_str(), ios::in);
if (file)
{
file.getline(line,10,'/');
heightTree = atoi(line);
file.getline(line,10);
while (!file.eof())
{
file.getline(line,10,'|');
int S = atoi(line);
Save.push_back(S);
}
}
else ShowMessage("Ошибка открытия файла");
file.close();
Fibonacci.DelTree (Fibonacci.GetChange());
Memo1->Lines->Clear();
Memo1->Lines->Add("Fibonacci Tree");
Fibonacci.TreeGener (heightTree,Fibonacci.GetChange());
sizeTree = 1;
Fibonacci.TreeFill (Fibonacci.GetChange(),&sizeTree);
//reverse(Save.begin(), Save.end()); //поворот вектора для pop
Fibonacci.GetSave(Fibonacci.GetPrint());
for (int i=0; i < Save.size()-1; i++)
{
sizeTree = Fibonacci.AddNode (Fibonacci.GetChange(), &sizeTree, Save[i]);
}
}
else ShowMessage("Такого файла не существует");
}
Timer1->Enabled = true;
Fibonacci.PrintTree (Fibonacci.GetPrint(),0);
}
//---------------------------------------------------------------------------
//добавление узла
void __fastcall TForm1::AddBClick(TObject *Sender)
{
try {
int data = 0;
if (ValueCB->Checked) data = StrToInt(ValueE->Text);
sizeTree = Fibonacci.AddNode (Fibonacci.GetChange(), &sizeTree, data);
Memo1->Lines->Clear();
Memo1->Lines->Add("Fibonacci Tree");
Fibonacci.PrintTree (Fibonacci.GetPrint(),0);
}
catch (...) { MessageBox(0, L"Введите целое число!", L"Ошибка!", MB_OK); }
}
//---------------------------------------------------------------------------
//изменение значения узла
void __fastcall TForm1::EditBClick(TObject *Sender)
{
try {
int key = StrToInt(KeyEdE->Text);
int data = StrToInt(ValueEdE->Text);
Fibonacci.EditValue (Fibonacci.GetChange(), key, data);
Memo1->Lines->Clear();
Memo1->Lines->Add("Fibonacci Tree");
Fibonacci.PrintTree (Fibonacci.GetPrint(),0);
}
catch (...) { MessageBox(0, L"Введите целое число!", L"Ошибка!", MB_OK); }
}
//---------------------------------------------------------------------------
//отключение компонентов изначально
void __fastcall TForm1::FormCreate(TObject *Sender)
{ ValueE->Enabled = false; KeyDelE->Enabled = false; }
//---------------------------------------------------------------------------
//переключение доступности компонентов
void __fastcall TForm1::ValueCBClick(TObject *Sender)
{ ValueE->Enabled = (ValueE->Enabled)? false : true; }
void __fastcall TForm1::DelRB1Click(TObject *Sender)
{ KeyDelE->Enabled = false; }
void __fastcall TForm1::DelRB2Click(TObject *Sender)
{ KeyDelE->Enabled = (ValueE->Enabled)? false : true; }
void __fastcall TForm1::DelRB3Click(TObject *Sender)
{ KeyDelE->Enabled = (ValueE->Enabled)? false : true; }
//создание дерева
void __fastcall TForm1::CreateBClick(TObject *Sender)
{
Fibonacci.DelTree(Fibonacci.GetChange());
Memo1->Lines->Clear();
Memo1->Lines->Add("Fibonacci Tree");
try { heightTree = StrToInt(CreateE->Text); }
catch (...) { MessageBox(0, L"Введите целое число больше 0!", L"Ошибка!", MB_OK); }
sizeTree = 1;
Fibonacci.TreeGener (heightTree,Fibonacci.GetChange());
Fibonacci.TreeFill (Fibonacci.GetChange(),&sizeTree);
Fibonacci.PrintTree (Fibonacci.GetPrint(),0);
Timer1->Enabled = true;
}
//---------------------------------------------------------------------------
//таймер значений
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
SizeL->Caption = IntToStr(sizeTree-1);
int Max = Fibonacci.MaxKey(Fibonacci.GetPrint());
int Min = Fibonacci.MinKey(Fibonacci.GetPrint());
MaxL->Caption = IntToStr(Max);
MinL->Caption = IntToStr(Min);
}
//---------------------------------------------------------------------------
//заполнение случайными значениями
void __fastcall TForm1::RandBClick(TObject *Sender)
{
randomize();
for (int key = 1; key < sizeTree; key++)
{
Fibonacci.EditValue (Fibonacci.GetChange(), key, random(100));
}
Memo1->Lines->Clear();
Memo1->Lines->Add("Fibonacci Tree");
Fibonacci.PrintTree (Fibonacci.GetPrint(),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
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
| //Тут описаны класс и структура дерева. А так же методы использующие компоненты
//или переменные из Mani.h
#include <vector>
using namespace std;
#include "Main.h"
template<class D>
struct Node;
template<class D>
class Tree;
extern vector<int> Save;
//узел дерева
template<class D>
struct Node
{
int Key; //ключ
Node* Left; //указатель на левую ветвь
Node* Right; //указатель на правую ветвь
//int Balance; //показатель баланса //ВНЕСТИ
//int Hight; //высота поддерева //ВНЕСТИ
D Data; //данные
};
//класс дерева
template<class D>
class Tree
{
private:
Node<D>* Root; //указатель на корень дерева
public:
Tree() { Root = nullptr; };
void TreeGener (int, Node<D>**);
void TreeFill (Node<D>**,int*);
void PrintTree (Node<D>*, int);
//void CanvasTree (Node<D>*, int, int);
int AddNode (Node<D>**, int*, D);
void EditValue (Node<D>** T, int, int);
void DelSubTree (Node<D>**, int, Node<D>**);
void DelTree(Node<D>**);
void DelNode (Node<D> **, int);
void DelNode_2 (Node<D> **, Node<D> **);
//bool CompNode(Node<D> **);
int MaxKey(Node<D>*);
int MinKey(Node<D>*);
void SetSave (Node<D>* );
void GetSave (Node<D>* );
Node<D>** GetChange() {return &Root;}; //получить для изменения
Node<D>* GetPrint() {return Root;}; //получить для печати
};
//PrintTree - печать дерева в Memo. T - указатель на корень, l - отступы
template<class D>
void Tree<D>::PrintTree (Node<D>* T, int l)
{
int i;
AnsiString str="";
if (T!=NULL)
{
PrintTree (T->Right,l+1);
for (i=1;i<=l;i++) str+=" ";
Form1->Memo1->Lines->Add(str+T->Key+"|"+T->Data);
PrintTree (T->Left,l+1);
}
}
/*
template<class D>
void Tree<D>::CanvasTree (Node<D>* T, int dX, int dY)
{
if (T!=NULL)
{
Form1->Image1->Canvas->TextOutW(X+dX,Y+dY,T->Key);
//Form1->Image1->Canvas->Ellipse(30,30,60,60);
if ((T->Left != NULL) && (T->Left->Key < T->Key))
{
dY+=30; dX-=30;
}
else
if((T->Right != NULL) && (T->Right->Key > T->Key)) //непроходит
{
dY+=30; dX+=30;
}
CanvasTree (T->Left, dX, dY);
CanvasTree (T->Right, dX, dY);
}
}
*/
//SetSave - записывает данные в вектор. T - указатель на корень
template<class D>
void Tree<D>::SetSave (Node<D>* T)
{
if (T!=NULL)
{
Save.push_back(T->Data);
SetSave(T->Left);
SetSave(T->Right);
}
}
//GetSave - получает данные из вектора. T - указатель на корень
template<class D>
void Tree<D>::GetSave (Node<D>* T)
{
if (T!=NULL)
{
T->Data = Save[0];
Save.erase(Save.begin());
GetSave(T->Left);
GetSave(T->Right);
}
} |
|
И код с методами класса:
| 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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
| //Тут описаны методы класса
//TreeGener - генерирует узлы дерева. k - высота дерева, T - указатель на корень
template<class D>
void Tree<D>::TreeGener (int k, Node<D>** T)
{
if (k==0) (*T) = NULL;
else
if (k==1)
{
(*T) = new (Node<D>);
(*T)->Left = (*T)->Right = NULL;
}
else
{
(*T) = new (Node<D>);
TreeGener (k-1,&((*T)->Left));
TreeGener (k-2,&((*T)->Right));
}
}
//TreeFill - заполняет узлы дерева ключами. T - указатель на корень, i - ключ
template<class D>
void Tree<D>::TreeFill (Node<D>** T,int* i)
{
if ( (*T)!=NULL )
{
TreeFill (&((*T)->Left),i);
(*T)->Key = (*i);
(*T)->Data = 0;
(*i)++;
TreeFill (&((*T)->Right),i);
}
}
//AddNode - добавляет узел в деревою. Root - указатель на корень, key - добавляемый узел
template<class D>
int Tree<D>::AddNode (Node<D> **Root, int* key, D data)
{
if (*Root)
{
if ((*key) < (*Root)->Key) AddNode (&(*Root)->Left, key, data);
else AddNode (&(*Root)->Right, key, data);
}
else
{
Node<D> *node = new Node<D>;
node->Key = (*key);
(*key)++;
//SizeTree = (*key); //изменение размера дерева
node->Data = data;
node->Left = nullptr;
node->Right = nullptr;
(*Root) = node;
}
return (*key); //изменение размера дерева
}
//EditValue - изменяет значение узла. T - указатель на корень, key - ключ, data - данные
template<class D>
void Tree<D>::EditValue (Node<D>** T, int key, int data) //запись ключей в вектор
{
if ((*T)!=NULL)
{
if ((*T)->Key == key)
{
(*T)->Data = data;
return;
}
EditValue(&(*T)->Left, key, data);
EditValue(&(*T)->Right, key, data);
}
}
//DelSubTree - удаляет поддерево. node - указатель на корень, del - удаляемый узел,
//pre - указатель для обращения к предку
template<class D>
void Tree<D>::DelSubTree (Node<D> **node, int del, Node<D> **pre)
{
Node<D> *cur;
if (*node==nullptr) return;
else
if (del<(**node).Key)
{
pre = node;
DelSubTree (&((**node).Left),del,pre);
}
else
if (del>(**node).Key)
{
pre = node;
DelSubTree (&((**node).Right),del,pre);
}
else
{
cur = *node;
DelTree(&cur);
if (del<(**pre).Key) (*pre)->Left=nullptr;
else (*pre)->Right=nullptr;
}
}
//DelTree - удаляет всё дерево. T - указатель на корень
template<class D>
void Tree<D>::DelTree(Node<D>** T)
{
if ((*T)!=NULL)
{
DelTree(&(*T)->Left);
DelTree(&(*T)->Right);
delete (*T);
}
(*T) = NULL;
}
//DelNode - удаляет узел. node - указатель на корень, del - удаляемый узел
template<class D>
void Tree<D>::DelNode (Node<D> **node, int del)
{
Node<D> *cur;
if (*node==NULL) return;
else
if (del<(**node).Key)
DelNode (&((**node).Left),del);
else
if (del>(**node).Key)
DelNode (&((**node).Right), del);
else
{
cur = *node;
if ((*cur).Right==NULL)
{
*node = (*cur).Left;
delete cur;
}
else
if ((*cur).Left==NULL)
{
*node = (*cur).Right;
delete cur;
}
else DelNode_2 (&((*cur).Left),&cur);
}
}
//DelNode_2 - вспомогательная функция удаления узла, для случая, когда удаляемый узел
//имеет 2 потомка. next - указатель потомка, cur - указатель на удаляемый узел
template<class D>
void Tree<D>::DelNode_2 (Node<D> **next, Node<D> **cur)
{
Node<D> *temp;
if ((**next).Right==NULL)
{ (**cur).Key = (**next).Key;
*cur = *next;
temp = *next;
*next = (**next).Left;
delete temp; }
else DelNode_2 (&((**next).Right),cur);
}
/*
//переделать под занесение Баланса
template<class D>
bool Tree<D>::CompNode(Node<D> **node)
{
if ((*node)->Left == NULL && (*node)->Right == NULL)
return true;
int left, right;
if ((*node)->Left != NULL)
left = CompNode(&(*node)->Left);
else
left = 0;
if ((*node)->Right != NULL)
right = CompNode(&(*node)->Right);
else
right = 0;
if (left == right) return true;
else return false;
}
*/
//MaxKey - возвращает максимальный ключ дерева. T - указатель на корень
template<class D>
int Tree<D>::MaxKey(Node<D>* T)
{
while (T->Right!=NULL)
T = T->Right;
return T->Data;
}
//MinKey - возвращает минимальный ключ дерева. T - указатель на корень
template<class D>
int Tree<D>::MinKey(Node<D>* T)
{
while (T->Left!=NULL)
T = T->Left;
return T->Data;
} |
|
Всё это вместе с проектом формы, и файлом аналогичной курсовой (я пытался по нему сделать, особо не вышло) прикладываю в архив Fibonacci Tree.rar
Разрабатывал в RAD Studio 10.3
Очень надеюсь на помощь!
0
|