Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Metod_lab_chast_1.doc
Скачиваний:
60
Добавлен:
01.02.2015
Размер:
1.43 Mб
Скачать

Лабораторна робота № 8

Тема: дерева.

Мета: набути досвід практичної роботи з бінарними деревами.

Теми для попередньої роботи:

  • нелінійні списки;

  • графи;

  • дерева;

  • операції на деревах.

Загальні відомості

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

Дерева можна представляти за допомогою нелінійних списків (спискове представлення) і масивів (послідовне представлення). Число ребер орієнтованого графа, що виходять з деякої вершини, називається напівступенем виходу цієї вершини. Дерева, в яких напівступінь виходу кожної вершини ≤ m (де m може дорівнювати 0,1,2,3 і т.д.) називають m-арними. Такі дерева, для яких m=2, називають бінарними. Дерева будь-якої арності можна перетворити в бінарне.

Типове завдання

Створити бінарне дерево, в якому ключи не повторюються і видати його. Значення полів вузлів дерева за рішенням користувача вводити з клавіатури або генерувати.

Текст програми

#include<conio.h>

#include<stdlib.h>

#include<iostream>

using namespace std;

class CtreeNode

{public:

int key; //ключ

int info; //информационное поле

CtreeNode *LLink, *RLink; //указатель на левый и правый узел

CtreeNode(){key=0;LLink=RLink=NULL;} //конструктор по умолчанию

CtreeNode(int k, int info_c){key=k;info=info_c;LLink=RLink=NULL;} //конструктор с параметр

~CtreeNode() //Деструктор

{ if(RLink!=NULL)delete RLink; //удалить левый и правый узел

if(LLink!=NULL)delete LLink;

}

//функция добавления элемента в дерево. Возвращает указатель на корень

void Insert(int number, int info, CtreeNode *ptr);

void PrintTree(CtreeNode *ptr, int n);

};

void CtreeNode::Insert(int n, int inf, CtreeNode *ptr)

{ //cout<<"----------------"<<endl;

cout<<"Добавляется элемент ("<<n<<";"<<inf<<")\n";

int flag=1;

CtreeNode *p, *q;

p=ptr;

while(flag)

{ if(n < p->key)

{ q=p->LLink; //a3

cout<<"Найден узел "<<p->key<<endl<<"Переход влево на элемент ";

if(q==NULL) cout<<"NULL"<<endl;

else cout<<q->key<<endl;

if(q==NULL)

{ flag=0;

cout<<"Создается новый элемент ("<<n<<","<<inf<<")"<<endl;

q=new CtreeNode(n,inf);

cout<<"Обновление связей: "<<p->key<<"->LLink = "<<q->key<<endl;

p->LLink=q;

} else p=q;

}

else if(n > p->key)

{ q=p->RLink; //a4

cout<<"Найден узел "<<p->key<<endl<<"Переход вправо на элемент ";

if(q==NULL)cout<<"NULL"<<endl;

else cout<<q->key<<endl;

if(q==NULL)

{ flag=0;

cout<<"Создается новый элемент ("<<n<<","<<inf<<")"<<endl;

q=new CtreeNode(n,inf);

cout<<"Обновление связей: "<<p->key<<"->RLink = "<<q->key<<endl;

p->RLink=q;

} else p=q;

}

else if(n == p->key)

{ cout<<"Такой элемент уже существует "<<endl;

flag=0;//выход из цикла WHILE

}

}

cout<<"\n Для продолжения нажмите Enter: \n";

getch();

}

void CtreeNode:: PrintTree(CtreeNode *ptr, int n)

{ if (ptr)

{ PrintTree(ptr->RLink, n+3);

for(int i=1;i<n;i++)

cout << " ";

cout<< ptr->key<<endl;

PrintTree(ptr->LLink, n+3);

}

}

void main() //главная программа

{ system("chcp 1251 > nul"); // для работи з кирилицей

int k_elem;

char rand_elem;

cout<<" Сколько элементов добавлять? ";

cin>>k_elem;

cout<<" Генерировать случайные элементы? (y/n) ";

cin>>rand_elem;

int num,inf;

if(rand_elem=='n')

{ cout<<endl<<"Индекс: "; //вводить с клавиатуры

cin>>num;

cout<<"Значение: ";

cin>>inf;

}

else

{ num=rand() % 100 + 1;//случайные значения

inf=rand() % 100 + 1;

}

CtreeNode *root=new CtreeNode(num,inf); //указатель на начало дерева

for(int tr_i=1;tr_i<k_elem;tr_i++)

{ if(rand_elem=='n')

{ cout<<endl<<"Индекс: "; //вводить с клавиатуры

cin>>num;

cout<<"Значение: ";

cin>>inf;

}

else

{ num=rand() % 100 + 1;//случайные значения

inf=rand() % 100 + 1;

}

root->Insert(num,inf,root);

}

root->PrintTree(root, 5);

//--- очистка памяти при выходе ---//

if(root!=NULL) delete root; //clear memory - binary trees

}

Фрагмент результатів роботи програми

Сколько элементов добавлять? 9

Генерировать случайные элементы? (y/n) y

Добавляется элемент (35;1)

Найден узел 42

Переход влево на элемент NULL

Создается новый элемент (35,1)

Обновление связей: 42->LLink = 35

Для продолжения нажмите Enter:

Добавляется элемент (70;25)

Найден узел 42

Переход вправо на элемент NULL

Создается новый элемент (70,25)

Обновление связей: 42->RLink = 70

. . . . . . . . . . . . . . . . . . . . . . . . .

Для продолжения нажмите Enter:

Добавляется элемент (96;43)

Найден узел 42

Переход вправо на элемент 70

Найден узел 70

Переход вправо на элемент 79

Найден узел 79

Переход вправо на элемент 82

Найден узел 82

Переход вправо на элемент NULL

Создается новый элемент (96,43)

Обновление связей: 82->RLink = 96

Для продолжения нажмите Enter:

96

82

79

70

63

62

42

35

6

Для продолжения нажмите любую клавишу . . .

Індивідуальні завдання

Розробити програму, що дозволяє створити бінарне дерево та вирішити індивідуальне завдання. В інформаційну частину вузлів записати ключ, що є цілим числом. Видати вміст дерева та результати індивідуального завдання на екран.

  1. Знайти вузол з max ключем; використати спадний обхід дерева із використанням стека.

  2. Знайти вузол з min ключем; використати висхідний обхід дерева із використанням стека.

  3. Визначити кількість вузлів, що мають max ключ; використати рекурсивний алгоритм змішаного обходу.

  4. Визначити кількість парних вузлів; використати змішаний обхід із використанням стека.

  5. Розробити програму турнірного сортування.

  6. Визначити K - кількість вузлів, ключ яких більше заданого числа N; використати рекурсивний алгоритм спадного обходу дерева; додати вузол з ключем K.

  7. Розробити програму обчислення висоти дерева.

  8. Розробити програму обчислення арифметичних виразів при спадному обході дерева. (В вузлах дерева записати операнди та операції арифметичного виразу у вигляді зворотнього польського запису).

  9. Розробити програму обчислення арифметичних виразів при висхідному обході дерева. (В вузлах дерева записати операнди та операції арифметичного виразу у вигляді зворотнього польського запису).

  10. Видалити вузли, ключ яких дорівнює заданому числу N.

  11. Створити два дерева: в одне переписати тільки парні ключі, а в друге – непарні.

  12. Додати після першого вузла з ключем K вузол з ключем N. Значення K та N ввести з клавіатури.

  13. Видалити вузли з непарними ключами.

  14. Визначити середньоарифметичне значення парних та непарних ключів дерева.

  15. Визначити кількість листів в дереві.

  16. Визначити кількість внутрішніх вузлів в дереві.

  17. Визначити кількість вузлів, що мають тільки ліве посилання (гілку).

  18. Визначити кількість вузлів, що мають тільки праве посилання (гілку).

  19. Порівняти час висхідного та спадного обходів дерева.

  20. Порівняти час висхідного та змішаного обходів дерева.

  21. Порівняти час змішаного та спадного обходів дерева.

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

  1. Що таке дерево?

  2. Чим визначається арність дерева?

  3. Які операції притаманні деревам?

  4. Що таке «обход» дерева, які операції обходу відомі?

  5. Напишіть структуру m-арного дерева за своїм розсудом. Поретворіть його в бінарне.

  6. Яке дерево називається деревом пошуку?

  7. Які виділяють типи дерев?

  8. Розкажіть алгоритм висхідного обходу дерева.

  9. Розкажіть алгоритм спадного обходу дерева.

  10. Розкажіть алгоритм змішаного обходу дерева.

  11. Яке дерево називається повним m-арним?

  12. Яке дерево називається ідеально збалансовоним?

  13. Яке дерево називається повним бинарним?

  14. Дано арифметичний вираз ((a + b) * (c – d) +f ) * k. Побудуйте для нього бінарне дерево.

  15. Запишіть арифметичний вираз за своїм розсудом. Створіть відповідне для нього дерево. Виконавши обход дерева, запишіть префіксну, інфіксну та посфіксну форми запису заданого виразу.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]