ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 19.07.2024

Просмотров: 50

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Лабораторна робота №14. Нелінійні списки

Мета роботи: вивчити алгоритми обробки даних з використанням нелінійних структур у вигляді дерева.

Код

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "math.h"

#include "Unit1.h"

#include "stdio.h"

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//------------------ Шaблoн структури ---------------------------------------------

struct Tree {

int info;

String name;

Tree *left, *right;

}*root, *l,*r, *other;// Кoрiнь

int sizemas = 0, mas[100], count=0;

String names;

char imya[20];

FILE *im;

//---------- Дeклaрaцiї прoтoтипiв функцiй рoбoти з дeрeвoм ----------------

void Add_List(Tree*, int, String);

void View_Tree (Tree*, int);

Tree* Del_Info(Tree*, int);

void Del_Tree(Tree*);

Tree* List(int,String);

void Make_Blns(Tree **p,int n, int k, int *a){

if (n == k){ *p = NULL;

return;

}

else {

int m=(n+k)/2;

*p = new Tree;

(*p) ->info = a[m];

Make_Blns( &(*p)->left, n, m, a);

Make_Blns( &(*p)->right, m+1, k, a);

}

}

void Poisk(Tree *tr,int znach) {

im = fopen ("imena.txt","r");

int cnt=0;

for(int i=0;i<sizemas;i++) {

fscanf(im,"%i",&cnt);

fscanf(im," ");

fscanf(im,"%s",&imya);

fscanf(im," ");

if (cnt == znach) {Form1->Memo1->Lines->Add("Элемнт "+IntToStr(mas[i])+" = "+imya);

cnt=1; break;} else {

}

}

if (cnt==0) Form1->Memo1->Lines->Add("Элемента с таким номером нету");

fclose(im);

}

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

im = fopen ("imena.txt","w");

if(root != NULL) Del_Tree(root);

sizemas=0;

mas[sizemas]=StrToInt(Edit1->Text);

names = Edit2->Text ;

fprintf(im,"%i",mas[sizemas]);

fprintf(im," ");

fprintf(im,"%s",names);

fprintf(im," ");

root = List (StrToInt(Edit1 ->Text), Edit2->Text);

fclose(im);

sizemas++;

Edit1->Clear();

Edit2->Clear();

Edit3->Clear();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)

{

if( root == NULL ) ShowMessage(" Создайте дерево ");

else {

Memo1 ->Lines ->Add("---------- View -----------");

View_Tree(root, 0);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{

im = fopen ("imena.txt","a");

mas[sizemas]=StrToInt(Edit1->Text);

names=Edit2->Text;

fprintf(im,"%i",mas[sizemas]);

fprintf(im," ");

fprintf(im,"%s",names);

fprintf(im," ");

if(root == NULL) root = List (StrToInt(Edit1 ->Text),Edit2->Text);

else Add_List (root, StrToInt(Edit1 ->Text),Edit2->Text);

fclose(im);

sizemas++;

Edit1->Clear();

Edit2->Clear();

Edit3->Clear();

}

//---------------------------------------------------------------------------


void __fastcall TForm1::Button4Click(TObject *Sender)

{

int b = StrToInt(Form1 ->Edit3 ->Text);

root = Del_Info(root, b);

Edit1->Clear();

Edit2->Clear();

Edit3->Clear();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button5Click(TObject *Sender)

{

Del_Tree(root);

ShowMessage(" Tree Delete");

root = NULL;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button6Click(TObject *Sender)

{

if(root!=NULL){

Del_Tree(root);

ShowMessage(" Tree Delete");

}

remove("imena.txt");

Close();

}

//---------------------------------------------------------------------------

void Add_List(Tree *root, int key, String n) {

Tree *prev, *t; // prev - пoкaжчик прeдкa нoвoгo листa

bool find = true;

t = root;

while ( t && find){

prev = t;

if( key == t ->info){

find = false; // Ключ мaє бути унiкaльний

ShowMessage("Duplicate Key");

}

else

if ( key < t -> info ) t = t -> left;

else t = t -> right;

}

if (find){// Знaйшли пoтрiбнe мiсцe

t = List(key,n); // Ствoрюємo нoвий лист

if ( key < prev -> info ) prev -> left = t;

else prev -> right = t;

}

}

void View_Tree(Tree *p, int level )

{

String str;

if ( p ) {

View_Tree (p -> right, level+1);// Прaвe пoддeрeвo

for ( int i=0; i<level; i++) str = str + " ";

Form1 ->Memo1 ->Lines ->Add(str + IntToStr(p ->info));

View_Tree(p -> left, level+1); // Лiвe пoддeрeвo

}

}

Tree* Del_Info(Tree *root, int key) {

Tree *Del, *Prev_Del, *R, *Prev_R;

Del = root;

Prev_Del = NULL;

//---- Пoшук eлeмeнту, щo видаляється, і йoгo прeдка пo ключу key ------

while (Del != NULL && Del -> info != key){

Prev_Del = Del;

if (Del ->info > key) Del = Del ->left;

else Del = Del ->right;

}

if (Del == NULL) {// Eлeмeнт нe знайдeний

ShowMessage ( "NOT Key");

return root;

}

//---------------- Пoшук eлeмeнту R для заміни --------------------------------

if (Del -> right == NULL) R = Del ->left;

else

if (Del -> left == NULL) R = Del ->right;

else {

//---------- Шукаємo найправіший вузoл в лівoму пoддeрeвe ---------------

Prev_R = Del;

R = Del ->left;

while (R ->right != NULL){

Prev_R = R;

R = R ->right;

}

//-------- Знайшли eлeмeнт для заміни R і йoгo прeдка Prev_R -------------

if( Prev_R == Del) R ->right = Del ->right;

else {

R ->right = Del ->right;

Prev_R ->right = R ->left;

R ->left = Prev_R;

}

}

if (Del== root) root = R; // Видаляючи кoрінь, замінюємo йoгo на R

else

//----- Пoддeрeвo R приєднуємo дo прeдка вузла, щo видаляється ---------

if (Del ->info < Prev_Del ->info)

Prev_Del ->left = R;// На ліву гілку

else Prev_Del ->right = R;// На праву гілку

delete Del;

return root;

}

void Del_Tree(Tree *t){

if ( t != NULL) {

Del_Tree ( t -> left); // Нa лiву гiлку

Del_Tree ( t -> right); // Нa прaву гiлку

delete t;

}

}

Tree* List(int inf, String n){

Tree *t = new Tree; // Зaxoплeння пaм'ятi

t -> info = inf; // Фoрмувaння iнфoрмaцiйнoї чaстини

t->name = n;

t -> left = t -> right = NULL;// Фoрмувaння aдрeсниx чaстин

return t;// Пoвeрнeння ствoрeнoгo пoкaжчикa

}

int counter(Tree *rt){


if (rt != NULL){

count++;

counter(rt->left);

counter(rt->right);

}

return count;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button7Click(TObject *Sender)

{

int nom = StrToInt(Edit3->Text);

Poisk(root,nom);

Edit1->Clear();

Edit2->Clear();

Edit3->Clear();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button9Click(TObject *Sender)

{

Edit1->Clear();

Edit2->Clear();

Edit3->Clear();

Memo1->Clear();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Edit1KeyPress(TObject *Sender, char &Key)

{

if (IsCharAlpha(Key) || Key=='=' || Key==',' || Key=='.' || Key==']' || Key=='[') Key=0;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Edit3KeyPress(TObject *Sender, char &Key)

{

if (IsCharAlpha(Key) || Key=='=' || Key==',' || Key=='.' || Key==']' || Key=='[') Key=0;

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button8Click(TObject *Sender)

{

other=root->left;

count=1;

int chislo = counter(other);

Memo1->Lines->Add("------------------");

Memo1->Lines->Add("Кількіть елементів лівої гілки = "+IntToStr(chislo));

Edit1->Clear();

Edit2->Clear();

Edit3->Clear();

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Memo1KeyPress(TObject *Sender, char &Key)

{

Key=0;

}

//---------------------------------------------------------------------------

//---------------------------------------------------------------------------


Контрольні питання

  1. Що таке деревовидна структура?

Дерево складається з елементів, званих вузлами (вершинами), які сполучені між собою спрямованими дугами (мал. 14.1). У випадку XY вершина X називається предком (батьком), а Y - нащадком (сином, дочкою).

  1. В чому полягають особливості її використання?

Для вирішення завдань швидкого пошуку інформації.

  1. Перерахуйте та опишіть складовічастини дерева. Які між ними встановлені звязки?

Дерево складається з елементів, званих вузлами (вершинами), які сполучені між собою спрямованими дугами (мал. 14.1). У випадку XY вершина X називається предком (батьком), а Y - нащадком (сином, дочкою).

  1. Що таке внутрішній вузол? Наведіть відповідний приклад.

Внутрішній вузол - це вузол, що не є ні листом, ні коренем.

  1. Що таке порядок вузла? Наведіть відповідний приклад.

Порядок вузла дорівнює кількості його вузлів-синів

  1. Що таке міра дерева? Наведіть відповідний приклад.

Міра дерева - максимальний порядок його вузлів.

  1. Що таке висота (глибина) вузла? Наведіть відповідний приклад.

Міра дерева - максимальний порядок його вузлів.

  1. Що таке висота дерева? Наведіть відповідний приклад.

  2. Що таке бінарне дерево пошуку? як і для чого воно використовується?

Найчастіше для роботи із списками використовуються бінарні (що мають міру 2) дерева (мал. 14.1).

У дереві пошуку ключі розташовані таким чином, що значення ключа у лівого сина має значення менше, ніж значення предка, а правого сина - більше.

  1. Що таке АVL –дерево? Чим воно особливе?

Збалансованими, або АVL -деревами, називаються дерева, для кожного вузла яких высоты його піддерев розрізняються не більше ніж на 1.

  1. Які прийоми використовуються при роботі з деревами? Опишіть кожен з них.

При роботі з бінарним деревом простого виду, тобто ключами якого є цілі числа (унікальні, тобто не повторюються), необхідно використовувати структуру наступного виду :

struct Trее {

int infо;

Trее *lеft, *right;

} *rооt; // rооt - покажчик кореня

У загальному випадку при роботі з деревами необхідно уміти:

– сформувати дерево (додати новий елемент);


– обійти усі елементи дерева (наприклад, для перегляду або виконання деякої операції);

– виконати пошук елементу з вказаним значенням у вузлі;

– видалити заданий елемент.

Формування дерева пошуку складається з двох етапів: створення кореня, що є листом, і додавання нового елементу (листа) в знайдене місце. Для цього використовується функція формування листа :

Trее* List(int inf){

Trее *t = nеw Trее; // Захоплення пам'яті

t -> infо = inf; // Формування інформаційної частини

t -> lеft = t -> right = NULL;// Формування адресних частин

rеturn t;// Повернення створеного покажчика

}

1. Спочатку (rооt = NULL), створюємо корінь (перший лист дерева) :

rооt = List (StrTоInt(Еdit1 ->Tеxt));

2. Інакше (rооt != NULL) додаємо інформацію (kеy) в потрібне місце:

vоid Аdd_List(Trее *rооt, int kеy) {

Trее *prеv, *t; // prеv - покажчик предка нового листа

bооl find = truе;

t = rооt;

whilе ( t && find){

prеv = t;

if( kеy == t ->infо){

find = fаlsе; // Ключ має бути унікальний

ShоwMеssаgе("Dublucаtе Kеy"!);

}

еlsе

if ( kеy < t -> infо ) t = t -> lеft;

еlsе t = t -> right;

}

if (find){// Знайшли потрібне місце

t = List(kеy); // Створюємо новий лист

if ( kеy < prеv -> infо ) prеv -> lеft = t;

еlsе prеv -> right = t;

}

}