46256 (Ссылочные типы. Динамические переменные), страница 3

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

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

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

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

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

NextElem: Pointer

end;

Stack= Assoc;

Рассмотрим реализацию основных операций над стеком.

3.7 Создание (очистка) стека

Для создания нового пустого или очистки существующего стека достаточно присвоить указателю на первый его элемент (вершину) значение nil.

procedure CreateStack ( var StackHead: Stack);

begin

StackHead:= nil

end;

3.8 Проверка стека на пустоту

Условием пустоты стека является значение его вершины, равное nil.

function StackIsClear( var StackHead: Stack ): Boolean;

begin

StackIsClear:= ( StackHead= nil )

end;

3.9 Занесение элемента в стек

Для включения элемента в стек, необходимо создать новый элемент типа стек, затем инициализировать его информационное поле. В заключение изменить его указатель и указатель на первый элемент стека так, чтобы первым стал новый элемент.

procedure IncludeInStack( var StackHead: Stack; NewElem: TypeOfElem );

var

ServiceVar: Stack;

begin

{создание нового элемента}

 new( ServiceVar );

ServiceVar^.Elem:= NewElem;

{созданный элемент сделать вершиной стека}

ServiceVar^.NextElem:= StackHead;

StackHead:= ServiceVar

end;

3.10 Выбор элемента из стека

При выполнении этой операции информационное поле элемента, находящегося в вершине стека, должно быть присвоено в качестве значения некоторой переменой, а сам элемент должен быть исключен из стека и уничтожен.

procedure SelectFromStack( var StackHead: Stack; var Result: TypeOfElem);

var

ServiceVar: Assoc;

begin

if StackHead <> nil then begin

{выбор элемента из вершины}

Result:= StackHead^.Elem;

{запоминание ссылки на старую вершину}

ServiceVar:= StackHead;

{исключение из стека и уничтожение элемента}

StackHead:= StackHead^.NextElem;

dispose( ServiceVar )

end

end;

Необходимо обратить внимание на введение вспомогательной переменной ссылочного типа ServiceVar для осуществления удаления элемента. Типична ошибка, связанная с попыткой решить эту задачу через dispose( StackHead ).

Разберем решение типичной задачи, связанной с обработкой стека.

Текст задания

Используя стек (считать уже описанными тип Stack с информационным элементом типа Char, функцию StackIsClear (проверка пустоты стека) и процедуры CreateStack (очистка стека), IncludeInStack (вставка элемента в стек), SelectFromStack (выборка элемента из стека)) решить следующую задачу: в текстовом файле f записана без ошибок формула следующего вида:

::= |M(,)|m(,)

цифра::= 0|1|2|3|4|5|6|7|8|9

где M обозначает функцию max, а m √ min. Вычислить (как целое число) значение данной формулы (например, M( 5, m( 6, 8)): 6).

Решение

program StackSample;

type

FileType= File of Char;

var

Source: FileType;

function formula( var t: FileType ): integer;

type

TypeOfElem= Char;

Assoc= ^ElementOfStack;

ElementOfStack= record

Elem: TypeOfElem;

NextElem: Pointer

end;

Stack= Assoc;

var

S: Stack;

c, op, x, y: char;

procedure CreateStack ( var StackHead: Stack);

begin

StackHead:= nil

end;

function StackIsClear( var StackHead: Stack ): Boolean;

begin

StackIsClear:= ( StackHead= nil )

end;

procedure IncludeInStack( var StackHead: Stack; NewElem: TypeOfElem );

var

ServiceVar: Stack;

begin

{создание нового элемента}

new( ServiceVar );

ServiceVar^.Elem:= NewElem;

{созданный элемент сделать вершиной стека}

ServiceVar^.NextElem:= StackHead;

StackHead:= ServiceVar

end;

procedure SelectFromStack( var StackHead: Stack; var Result: TypeOfElem );

var

ServiceVar: Assoc;

begin

if StackHead <> nil then begin

{выбор элемента из вершины}

Result:= StackHead^.Elem;

{запоминание ссылки на старую вершину}

ServiceVar:= StackHead;

{исключение из стека и уничтожение элемента}

StackHead:= StackHead^.NextElem;

dispose( ServiceVar )

end

end;

begin

reset( t );

CreateStack( S );

while not eof( t ) do begin

read(t, c);

{обработка очередной литеры текста (литеры ╚(╩ и ╚,╩ игнорируются)}

if c in ['0'..'9','M','m'] then IncludeInStack( S, c)

else

if c= ')' then begin {конец формулы вида p(x, y)}

{в конце стека находится тройка op x y, она удаляется

из стека, выполняется операция op и результат

записывается в стек}

SelectFromStack( S, y );

SelectFromStack( S, x );

SelectFromStack( S, op );

case op of

'M'{max}: if x > y then c:= x else c:= y;

'm'{min}: if x < y then c:= x else c:= y

end;

IncludeInStack( S, c )

end

end; {of while}

{в стеке осталась одна цифра √ значение всей формулы; цифра переводится в целое число}

SelectFromStack( S, c );

formula:= ord( c ) - ord( '0' )

end;

begin

assign( Source, 'c:\temp\source.txt' );

writeln( Formula( Source ) );

end.

4. Двоичные деревья

Элементы двоичного дерева помимо информативной части имеют две ссылки √ на нижний левый и на нижний правый элементы. Принцип построения двоичного дерева заключается в том, что очередной элемент в зависимости от значения информативной части должен попасть в правое (если информационная часть включаемого элемента больше информационной части корня) или левое (в противном случае) поддерево. При этом в рамках выбранного поддерева определение местоположения нового элемента производится аналогично (см. рис. 7).

Данную структуру целесообразно описать следующим образом:

type

TypeOfElem= {};

Assoc= ^ElemOfTree;

ElemOfTree= record

Elem: TypeOfElem;

Left, Right: Pointer

end;

4.1 Поиск элемента в дереве

function FoundInTree( Elem: TypeOfElem; var Tree, Result: Pointer ): Boolean;

var

ServiceVar: Assoc;

b: Boolean;

begin

b:= False;

ServiceVar:= Tree;

if Tree <> nil then

repeat

if ServiceVar^.Elem= Elem then b:= True

else

if Elem < ServiceVar^.Elem then ServiceVar:= ServiceVar^.Left

else ServiceVar:= ServiceVar^.Right

until b or ( ServiceVar= nil );

FoundInTree:= b;

Result:= ServiceVar

end;

4.2 Включение элемента в дерево

Включение элемента в дерево реализуется путем во-первых, поиска вершины √ предка нового элемента, во-вторых, непосредственным включением элемента в дерево по найденной позиции. Опишем процедуру поиска предка для нового элемента.

function SearchNode( Elem: TypeOfElem; var Tree, Result: Assoc): Boolean;

var

ServiceVar1, ServiceVar2: Assoc;

b: Boolean;

begin

b:= False;

ServiceVar1:= Tree;

if Tree <> nil then

repeat

ServiceVar2:= ServiceVar1;

if ServiceVar1^.Elem= Elem then {элемент найден} b:= True

else begin

{запоминание обрабатываемой вершины}

ServiceVar2:= ServiceVar1;

if Elem < ServiceVar1^.Elem then ServiceVar1:=

ServiceVar1^.Left

else ServiceVar1:= ServiceVar1^.Right

end

until b or ( ServiceVar1= nil );

SearchNode:= b;

Result:= ServiceVar2

end;

Как видно из описания, эта функция подобна ранее рассмотренной функции поиска элемента дерева (FoundInTree), но в качестве побочного эффекта фиксируется ссылка на вершину, в которой был найден заданный элемент (в случае успешного поиска), или ссылка на вершину, после обработки которой поиск прекращен (в случае неуспешного поиска). Сама процедура включения элемента в дерево будет иметь следующее описание.

procedure IncludeInTree( Elem: TypeOfElem; var Tree: Assoc );

var

Result, Node: Assoc;

begin

if not SearchNode( Elem, Tree, Result ) then begin

{формирование новой вершины в дереве}

new( Node );

Node^.Elem:= Elem;

Node^.Left:= nil;

Node^.Right:= nil;

if Tree= nil then

{если дерево пусто, то созданный элемент сделать вершиной дерева}

Tree:= Node

else

{подсоединить новую вершину к дереву}

if Elem < Result^.Elem then Result^.Left:= Node

else Result^.Right:= Node

end

end;

Двоичное дерево можно рассматривать как рекурсивную структуру данных, состоящую из корневой записи, указывающей на левое и правое поддерево. Оба поддерева имеют такую же структуру: корень поддерева и правое и левое поддеревья. При этом, для представления дерева рекурсивной динамической структурой целесообразно модифицировать описание типа дерева, данное выше. А именно, удобнее изменить тип ссылок на левое и правое поддеревья с нетипизированного (Pointer) на типизированный:

type

TypeOfElem1= {};

Assoc1= ^ElemOfTree1;

ElemOfTree1= record

Elem: TypeOfElem1;

Left, Right: Assoc1

end;

Опишем процедуру вставки элемента рекурсивно.

procedure IncludeInTree2( NewElem: Assoc1; var SubTree: Assoc1 );

begin

if SubTree= nil then begin

SubTree:= NewElem;

NewElem^.Left:= nil;

NewElem^.Right:= nil;

end

else

if NewElem^.Elem < SubTree^.Elem then

IncludeInTree2( NewElem, SubTree^.Left )

else

IncludeInTree2( NewElem, SubTree^.Right )

end;

4.3 Удаление элемента дерева

Проблема реализации данной операции состоит в том, что в общем случае, в удаляемую вершину входит одна связь, а выходят две. Поэтому, необходимо найти подходящий элемент дерева, который можно было бы вставить на место удаляемого. Этот элемент является либо самым правым элементом левого поддерева (для достижения этого элемента необходимо перейти в следующую вершину по левой ветви, а затем, переходить в очередные вершины по правым ветвям до тех пор, пока очередная такая ссылка не будет равна nil), либо самый левый элемент правого поддерева (для достижения этого элемента необходимо перейти в следующую вершину по правой ветви, а затем, переходить в очередные вершины по левым ветвям до тех пор, пока очередная такая ссылка не будет равна nil). Процедура исключения элемента из двоичного дерева должна различать тои случая:

1. элемента с заданной информативной частью в дереве нет; 2. элемент с заданной информативной частью имеет не более одной ветви; 3. элемент с заданной информативной частью имеет две ветви.

procedure DeleteElemOfTree( var Tree: Assoc1; Elem: TypeOfElem1 );

var

ServiceVar1: Assoc1;

procedure Del( var ServiceVar2: Assoc1 );

begin

if ServiceVar2^.Right= nil then begin

ServiceVar1^.Elem:= ServiceVar2^.Elem;

ServiceVar1:= ServiceVar2;

ServiceVar2:=ServiceVar2^.Left

end

else Del( ServiceVar2^.Right )

end;

begin

{удаление элемента с информативным полем равным Elem из дерева Tree}

if Tree= nil then

{первый случай процедуры удаления}

writeln( 'Элемент не найден' )

else

{поиск элемента с заданным ключом}

if Elem < Tree^.Elem then DeleteElemOfTree( Tree^.Left, Elem )

else

if Elem > Tree^.Elem then

DeleteElemOfTree( Tree^.Right, Elem )

else begin

{элемент найден, необходимо его удалить}

ServiceVar1:= Tree;

{второй случай процедуры удаления}

if ServiceVar1^.Right= nil then

Tree:= ServiceVar1^.Left

else

if ServiceVar1^.Left= nil then

Tree:= ServiceVar1^.Right

else

{третий случай процедуры удаления}

Del( ServiceVar1^.Left )

end

end;

Вспомогательная рекурсивная процедура Del вызывается лишь в третьем случае процедуры удаления. Она переходит к самому правому элементу левого поддерева удаляемого элемента, а затем заменяет информационное поле удаляемого на значение поля найденного элемента.

4.4 Вывод элементов дерева

Данная задача также может быть решена с помощью механизма рекурсии.

procedure PrintTree( Tree: Pointer);

var

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