49184 (Структури даних для обробки інформації), страница 2

2016-07-30СтудИзба

Описание файла

Документ из архива "Структури даних для обробки інформації", который расположен в категории "". Всё это находится в предмете "информатика" из 1 семестр, которые можно найти в файловом архиве . Не смотря на прямую связь этого архива с , его также можно найти и в других разделах. Архив можно найти в разделе "курсовые/домашние работы", в предмете "информатика, программирование" в общих файлах.

Онлайн просмотр документа "49184"

Текст 2 страницы из документа "49184"

елемент3

елемент2

елемент1

Розглянемо докладніше як працює з попереднього прикладу структура:

new(a);

a^.name:=name;

a^.next:=a1;

a1:=a;


new(a);




a^.name:=name;



a^.next:=a1;



a1:=a;



При повторному виконанні вказівок:

new(a);

a^.name:=name;

a^.next:=a1;

a1:=a;

в пам’яті ПК відбудуться наступні перетворення:


Бачимо, що кожен наступний елемент (Name2) встановлюється на початок списку. Останній елемент, який увійде у стек – перший з нього виходить (він буде на першому місці, тобто при читанні стеку, буде першим).

1.3. ЗВ’ЯЗАНИЙ СПИСОК. ЧЕРГА.

Формування черги (вставка елементів в кінець списку).

sn



s1

Список до внесення елемента «Ільчук» в чергу


Іванов

Петров

Сидоров


Ільчук


s



sn


Список після внесення елемента «Ільчук» в чергу


s1


Іванов

Петров

Сидоров


Ільчук


s



Після створення динамічної змінної s^,поміщаємо в неї «Ільчук». Потім необхідно на цей елемент «напрямити» вказівник елемента sn^ (динамічна змінна sn^ містить вказівник next . А отже, sn^.next:=s;). Після цього елемент «Ільчук» добавиться в кінець списку. Але вказівник sn ще вказує на попередньо останній елемент (тобто на «Сидоров»). Напрямимо його на «Ільчук» (на «Ільчук вказує s. Отже, sn:=s).

Розглянемо схематично дію програмного коду вставки елемента в чергу.



t ype

elem=^zapis;

zapis=record

name:string;

next:elem;

end;

var

s1, s, sn:elem;

begin

new(s);

readln(name);

s^.name:=name;

s^.next:=nil;

if s1=nil then s1:=s

else sn^.next:=s;

sn:=s;

end.

В результаті роботи такої програми три вказівника будуть вказувати на перший елемент черги.

При повторному виконанні вказівок

new(s);

readln(name);

s^.name:=name;

s^.next:=nil;

if s1=nil then s1:=s

else sn^.next:=s;

sn:=s;

новий елемент s^ буде добавлено в кінець списку. При цьому s1 буде вказувати на перший елемент списку, а s та sn – на добавлений елемент списку (останній елемент).

Розглянемо на схемі повторну дію згаданих вище вказівок:





ТЕКСТ ПРОГРАМИ ФОРМУВАННЯ ЧЕРГИ:

type

elem=^zapis;

zapis=record

name:string;

next:elem;

end;

var s1, s, sn:elem;

name:string;

BEGIN

s1:=nil; s:=nil;

repeat

new(s);

readln(name);

if name<>’’ then begin

s^.name:=name;

s^.next:=nil;

if s1=nil then s1:=s;

else sn^.next:=s;

sn:=s;

end;

until name=’’;

while s1<>nil do begin

writeln('--',s1^.name);

s1:=s1^.next;

end;

END.

ФОРМУВАННЯ ВПОРЯДКОВАНОГО СПИСКУ.

S1 – вказівник на перший елемент списку

S_new – вказівник на новий елемент списку

S_p – вказівник на елемент, після якого необхідно здійснити вставку нового елемента

Buf – деякий допоміжний вказівник на елемент, який проглядається в процесі пошуку місця для вставки нового елемента.

type

elem=^spisok;

spisok=record

name:string;

next:elem;

end;

var

s1,s_new,buf,s_p:elem;

BEGIN

s1:=nil;s_new:=nil;buf:=nil;

repeat

new(s_new);

readln(s_new^.name);

s_p:=nil;

buf:=s1;

if s_new^.name<>'' then

begin

while (buf^.namenil) do

begin

s_p:=buf;

buf:=buf^.next;

if s_p=nil then

begin

s_new^.next:=s1;

s1:=s_new;

end

else

begin

s_new^.next:=s_p^.next;

_p^.next:=s_new;

end;

end;

until s_new^.name='';

while s1<>nil do

begin

writeln('--',s1^.name);

s1:=s1^.next;

end;

END.

ВИДАЛЕННЯ ЕЛЕМЕНТА ЗІ СПИСКУ

Якщо у деякому сформованому списку вказівник s_1 вказує на перший елемент списка, то програмний код знищення елементів, що вводяться з клавіатури (якщо він присутній у списку, то нехай buf – це вказівник на елемент, що знаходиться перед ним) , може мати наступний вигляд:

{Формування списку}

repeat

writeln('Введите элемент, который хотите уничтожить со списка:’);

readln(name);

if name<>'' then

begin

if s1^.name=name then s1:=s1^.next

else

begin

buf:=s1;

while (buf^.next^.name<>name)and(buf^.next<>nil) do buf:=buf^.next;

if buf^.next^.name=name then buf^.next:=buf^.next^.next;

end;

end;

until name='';

ОБЕРНЕННЯ ЕЛЕМЕНТІВ СПИСКУ (ЗМІНЕННЯ НАПРЯМКІВ УСІХ ВКАЗІВНИКІВ НА ПРОТИЛЕЖНИЙ)

1 спосіб (шляхом «переміщення» кожного елемента списку, починаючи з другого, на його початок)

Зауваження! Під переміщенням елемента розуміємо не фізичне переміщення його на початок списку. На початок списку «направляємо» лише вказівник елемента, який з даного списка видаляється.

S_1 – вказівник на перший елемент списку

S – вказівник на поточний елемент списку

Buf – вказівник на наступний за поточним елементом (на елемент що переміщається на початок списку

s:=s_1;

buf:=s_1;

while s^.next<>nil do

begin

buf:=s^.next;

s^.next:=s^.next^.next;

buf^.next:=s_1;

s_1:=buf;

end;

2 спосіб (шляхом зміни напрямків вказівників на протилежний)

S_1 – вказівник на перший елемент списку

S – вказівник на поточний елемент списку

Left – вказівник на елемент, що знаходиться лівіше від поточного

Right – вказівник на елемент, що знаходиться правіше від поточного

right:=s_1;

s:=nil;

repeat

left:=s;

s:=right;

right:=right^.next;

s^.next:=left;

until right=nil;


РОЗДІЛ ІІ. ДЕРЕВА. БІНАРНЕ ДЕРЕВО

Деревом називається динамічна структура, у якій кожен вузол містить не один, а декілька вказівників на декілька інших вузлів.

К ореневий вузол (корінь дерева) – це самий верхній вузол (вузол a – кореневий) . Якщо з деякого вузла (наприклад, вузла а) вказівники вказують на інші вузли (в нашому випадку на вузли b та c), то такий вузол називають предком. Вузли ж на які вказують вказівники від предка називаються потомками.

Все сказане вище ілюструє малюнок 1, якщо його розглянути то можна зробити висновки про те, що:

  • Лівий потомок вузла а – вузол b

  • Правий потомок – вузол c.

  • Вузли b та c мають спільного предка – вузол а

Якщо вузол не має потомків, то такий вузол називають листком дерева, тому згідно малюнка вершини d, g та f – є листками.

Дерево, кожен вузол якого не може мати більше двох потомків називається бінарним.

2.1. РЕАЛІЗАЦІЯ БІНАРНОГО ДЕРЕВА ЗА ДОПОМОГОЮ ДИНАМІЧНИХ ЗМІННИХ


Розглянемо динамічну змінну b, що має таку структуру, як показано на малюнку 2. А саме, змінна b є записам з 5 полів:

Parent –вказівник на предка

Left – вказівник на лівого потомка

Right – вказівник на правого потомка

Data – поле даних (наприклад, прізвище)

Key – ключ (цілочисельне значення), по якому ідентифікується елемент.

Тип такої динамічної змінної виглядає наступнич чином:

type

BinarTree=^node;

node=record

key:integer;

data:string;

left,right,
parent:BinarTree;

end;

Сформуємо дерево керуючись таким принципом: ключ кожного лівого потомка менший за ключ предка, а ключ правого потомка – більший або рівний ключа предка.

Н априклад, бінарне дерево з трьох вузлів (Іванов (ключ=5), Петров (ключ=3) та Сидоров (ключ=8)) має вигляд як показано на мал.3. Добавимо в дерево елемент Ільїн з ключем 6. Цей елемент буде лівим потомком елемента Сидоров (так як 6>5 та 6<8). Якби ключ елемента Ільїн був рівний 4, то він був би правим потомком елемента Петров (бо 4<5 та 4>3)

При вставці кожного наступного елемента (нехай вказівник b_new вказує на цей елемент) в дерево (b вказує на корінь цього дерева), ми повинні спочатку знайти листок (нехай на нього вказує вказівник b_parent), який буде предком елемента що вставляєть.

Для пошуку такого листка використаємо деякий проміжний вказівник b_buf, який спочатку буде вказувати на корінь дерева b, а потім крок за кроком приймати значення b_buf^.left або b_buf^.right в залежності від значенні ключа елемента що вставляється (b_new) до тих пір, поки не дойде до листка дерева.

Програмний код пошуку елемента b_parent.

b_buf:=b;

while b_buf<>nil do

begin
b_parent:=b_buf;
if b_new^.key then b_buf:=b_buf^.left

else b_buf:=b_buf^.right;

end;

Наступний крок – направити вказівник b_new^.parent на знайдений елемент b_parent та вказівники left або right знайденого елемента b_parent на елемент, що вставляється b_new:

Програмний код виставлення лівого та правого вказівників знайденого елемента-предка (b_parent^.left та b_parent^.right) на новий елемент (b_new) та вказівника нового елемента-потомка (b_new^.parent) на знайдений елемент-предок (b_parent):

b_new^.parent:=b_parent;if b_new^.key

else b_parent^.right:=b_new

ВИВЕДЕННЯ НА ЕКРАН ЛИСТКІВ БІНАРНОГО ДЕРЕВА.

Процедура виведення листів бінарного дерева є рекурсивною. Адже листками деякого дерева Х є листи його лівого та правого потомків (якщо ці потомки не nil). Назвемо процедуру виведення листка дерева write_tree(x:BinarTree). Якщо лівий та правий вказівники деякого елемента вказують на nil значить цей елемент є листом, а отже його треба вивести на екран. Інакше шукаємо листки лівого потомка (якщо він не рівний nil), а потім – правого потомка (якщо він також не рівний nil).

procedure write_tree(x:BinarTree);

begin

if (x^.left=nil) and (x^.right=nil) then write(x^.data,' ')

else

begin

if x^.left<>nil then write_tree(x^.left);

if x^.right<>nil then write_tree(x^.right);

end;

end;

ТЕКСТ ПРОГРАМИ ФОРМУВАННЯ БІНАРНОГО ДЕРЕВА
ТА ВИВЕДЕННЯ НА ЕКРАН ЙОГО ЛИСТІВ

uses crt;

type

BinarTree=^node;

node=record

key:integer;

data:string;

left,right,parent:BinarTree;

end;

var

b,b_parent,b_new,b_buf:BinarTree;

name:string;

k:integer;

procedure write_tree(x:BinarTree);

begin

if (x^.left=nil) and (x^.right=nil) then write(x^.data,' ')

else

begin

if x^.left<>nil then write_tree(x^.left);

if x^.right<>nil then write_tree(x^.right);

end;

end;

begin

clrscr;

repeat

write('Фамилия -> ');

readln(name);

if name<>'' then

begin

write('Ключ -> ');

readln(k);

new(b_new);

with b_new^ do

begin

parent:=nil;

left:=nil;right:=nil;

data:=name;

key:=k;

end;

if b=nil then b:=b_new

else

begin

b_buf:=b;

while b_buf<>nil do

begin

b_parent:=b_buf;

if b_new^.key

else b_buf:=b_buf^.right;

end;

b_new^.parent:=b_parent;

if b_new^.key

else b_parent^.right:=b_new

end;

end;

until name='';

write('Листы дерева: ');

write_tree(b);

writeln;

end.

Результат роботи програми:

Имя -> Иванов

Ключ -> 5

Имя -> Петров

Ключ -> 3

Имя -> Сидоров

Ключ -> 8

Имя -> Ильин

Ключ -> 6

Имя ->

Листі дерева: Петров Ильин

ВИВЕДЕННЯ НА ЕКРАН УСІХ ВУЗЛІВ БІНАРНОГО ДЕРЕВА

В идозмінимо процедуру виведення листів бінарного дерева в процедуру виведення усіх його вузлів: лівий потомок - правий потомок – предок - … - кореневий вузол:

procedure write_tree(x:BinarTree);

begin

if (x^.left<>nil) or (x^.right<>nil) then

begin

if x^.left<>nil then write_tree(x^.left);

if x^.right<>nil then write_tree(x^.right);

end;

write(x^.data,' ');

end;

Тут виведення вузлів здійснюється як результат зворотньої дії рекурсивної процедури (вказівка write(x^.data,' ') – вкінці процедури). При такій організації вузли розпочнуть виводитись на екран після досягнення крайнього лівого листка.

При введенні бінарного дерева, зображеного на малюнку 4, результат роботи описаної процедури буде наступним:

Все узлы дерева: 0 2 1 4 5 3 7 9 8 6 11 13 12 15 18 20 19 17 16 14 10

Якщо вказівку write(x^.data,' ') розмістити не в кінці, а на початку процедури, то виведення вузлів буде здійснюватися як результат прямої дії рекурсії. Тобто, спочатку виведуться усі ліві потомки кореня дерева, потім правий потомок предка крайнього лівого листка і всі його ліві потомки і т.д. аж до крайнього правого лиска дерева.

В цьому випадку при введенні того ж дерева (мал.4) результат роботи такої процедури наступний:

Все узлы дерева: 10 6 3 1 0 2 5 4 8 7 9 14 12 11 13 16 15 17 19 18 20

ВИЗНАЧЕННЯ КІЛЬКОСТІ РІВНІВ БІНАРНОГО ДЕРЕВА (ВИСОТИ ДЕРЕВА)

На малюнку 5 зображено шести-рівневе бінарне дерево. Лівий потомок (6) – 4-х рівневе дерево. Правий потомок (16) 5-ти рівневе дерево. Бачимо, що для того, щоб визначити висоту дерева необхідно до висоти «вищого» потомка додати 1. Виходячи з таких міркування функція визначення висоти дерева (Function height_tree(x:BinarTree):integer) має рекурсивний характер.

Нехай i – висота лівого потомка, а j – висота правого потомка. Тоді:

F unction height_tree(x:BinarTree):integer;

var

i,j:integer;

begin

if x=nil then height_tree:=0

else

begin

i:=height_tree(x^.left);

j:=height_tree(x^.right);

if i>j then height_tree:=i+1

else height_tree:=j+1;

end;

end;

При введенні дерева, зображеного на мал.5, результат роботи функції height_tree наступний:

Висота дерева: 6

ВИСНОВКИ

У виконаній роботі було розглянуто процеси пошуку інформацій та розроблено структури даних для ефективного зберігання та обробки інформації. Як приклад розглянуто бінарне дерево. Це динамічна структура даних, розмір якої обмежується тільки розміром віртуальної пам’яті комп’ютера. Бінарні дерева забезпечують пошук конкретного значення, максимуму, мінімуму, попереднього, наступного, операції вставки та видалення елемента.

Розглянуті у роботі бінарні структури широко використовуються у житті, наприклад це різноманітні "ієрархічні структури", які нині широко використовуються в багатьох комп'ютерних завданнях. На даний час також розвивається граматичний аналіз, в основі якого і знаходяться принципи бінарних дерев. Граматичний аналіз на даний час широко використовується у сучасних пошукових алгоритмах.

Тому вивчення бінарних дерев та їх функціонування має важливе значення.


СПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ.

  1. Никита Культин «Программирование в Turbo Pascal и Delphi» — СПб.: БХВ — Санкт-Петербург, 1999.

  2. С.А.Немнюгин «Turbo Pascal: практикум» — СПб.: Питер, 2001.

  3. Е.А.Зуев «Программирование на языке Turbo Pascal 6.0., 7.0. — Москва: Веста, Радио и связь, 1993.

  4. Аляев Ю.А., Козлов О.А. Программирование. Pascal, C++, Visual Basic. М.: Финансы и статистика, 2004.

  5. Гуденко Д., Петроченко Д. Сборник задач по программированию. – Спб.: Питер, 2003.

4



Свежие статьи
Популярно сейчас
Зачем заказывать выполнение своего задания, если оно уже было выполнено много много раз? Его можно просто купить или даже скачать бесплатно на СтудИзбе. Найдите нужный учебный материал у нас!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Нашёл ошибку?
Или хочешь предложить что-то улучшить на этой странице? Напиши об этом и получи бонус!
Бонус рассчитывается индивидуально в каждом случае и может быть в виде баллов или бесплатной услуги от студизбы.
Предложить исправление
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
5120
Авторов
на СтудИзбе
445
Средний доход
с одного платного файла
Обучение Подробнее