I:byte;ch,ch1:char;

begin strp:=’’;

stek:=Tlist.create;

for i:=1 to length(stri) do

begin

ch:=stri[i];

if not ch in[’+’,’-’,’*’,’/’,’(’,’)’,’^’]

then strp:=strp+ch// операнд записываем в вых. стр.

else

if stek.sp1=Nil then stec.Add1(ch) //если стек пуст 1)

else

if ch=’(’then stec.Add1(ch) //откр. Скобка 2)

else

if ch=’)’then // выталкиваем все операции 3)

begin

stec.Read1(ch);

While ch<>’(’do //до ближайшей (

begin

strp:=strp+ch;// в strp

stec.Read1(ch);

End

End

else

begin // выталкивание более приоритетных 4)

pc:=prior(ch);

While (stek.sp1<>Nil) and (pc<= prior(stek.sp1.Inf)) do

begin

stec.Read1(ch1);

strp:=strp+ch1;

end;

stec.Add1(ch); // добавить после выталкивания

end;

end;//for ` выталкивание оставшихся операций 5)

While stek.sp1<>nil do begin stec.Read1(ch);

strp:=strp+ch end;

end;//OBP

6.2. Сложение больших целых чисел

Задача ставится следующим образом: для двух чисел с произвольным количеством разрядов (превосходящим возможности стандартных ячеек) требуется выполнить операции сложения.

Число Р, содержащее n разрядов можно представить в виде односвязного списка spk из отдельных цифр этого числа, причем единицы находятся в конце списка. Так число Р=1256 будет размешено следующим образом:

Пусть u,v – два больших числа, w- их сумма, w=v+u.

Var su,sv,sw:Tlist;// три очереди

< Inf:Byte; >

Procedure SumBch(su,sv:Tlist;var sw:Tlist);

Var u,V,s,t:byte;

begin

sw:=Tlist.create; s:=0;// s=0 или 1- перенос в следующий разряд

q:=10;// основание системы счисления

While (su.sp1<>Nil) and (sv.sp1<>Nil) do

begin

t:=su.sp1^.Inf+ sv.sp1^.Inf+s;

sw.Addk(t mod q);

s:=t div q;

su.sp1:=su.sp1^.A; sv.sp1:=sv.sp1^.A;

// после сложения

end;//числа в списках su и sv сохраняются

While su.sp1<>Nil do

begin

t:=su.sp1.Inf+s;

sw.Addk(t mod q);

s:=t div q;

su.sp1:=su.sp1^.A;

end;

While sv.sp1<>Nil do

begin

t:=sv.sp1.Inf+s;

sw.Addk(t mod q);

s:=t div q;

sv.sp1:=sv.sp1^.A;

end;

if s>0 then sw.Addk(s);

end;

В результате сумма будет размещена в списке (sw) в виде аналогичном u и v. Аналогично выполняется вычитание, несколько сложнее умножение и целочисленное деление больших чисел. (Предлагается реализовать в качестве упражнения).

6.3. Работа с разреженными матрицами

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

Const nr=100;// максимальная размерность

Type

Tinf=Record

a:extended;// элемент матрицы с индексами i,j

key:word; // здесь key=j второй индекс

end;

TmList=Class(Tlist)

H:array[1..nr] of Tlist; // массив из списков

Inf:Tinf;

n:word; // размер матрицы

Constructor create;

Procedure Addm(i,j:word;a:extended);

Function Readm(i,j:word):extended;

Procedure Rev(k,l:word);

. . . . . . . .

End;

Constructor TmList.create;

Var i:word;

begin

Inherited create;

for i:=1 to n do ms[i].sp1:=Nil;

end;

Добавление ненулевого элемента в матрицу:

Procedure TmList.Addm(i,j:word;a:extended);

begin

Inf.a:=a;

Inf.key:=j;

H[i].add1(inf);// используем метод класса Tlist

end;

Чтение элемента матрицы:

Function TmList.Readm(i,j:word):extended;

Var a:extended;

begin

sp:=H[i].poisk(j,a);// используем метод Tlist

if sp<>Nil then result:=a else result:=0;

end;

Перестановка местами строк матрицы:

Procedure TmList.Rev(k,l:word);

Begin

sp:=H[k]; H[k]:=H[l]; H[l]:=sp;

end;

Тема 7. Древовидные структуры данных

7.1. Древовидная структура данных

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

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

Древовидное размещение списка данных (abcdefgkl) можно изобразить, например, следующим образом:

Рис 3.1.Древовидное размещение списка данных

Как видим данные размещаются в узлах дерева соединенных направленными дугами (ветвями). Если два узла соединены направленной дугой (xy) то узел х называется предшественником (родителем), а узел у – преемником (дочерью). Деревья имеют единственный узел (корень), у которого нет родителя. Узел, не имеющий дочерей называется листом. Внутренний узел – это узел, не являющийся листом или корнем. Порядок узла – количество его дочерних узлов. Степень дерева – максимальный порядок его узлов. Глубина узла равна числу его предков плюс 1. Глубина дерева – это наибольшая глубина его узлов. Дерево, представленное выше имеет степень 3 (троичное), глубину 4, корневой узел а, листы d, e, g, k, l.

Для реализации древовидных структур данных степени m используется следующая уже знакомая конструкция рекурсивного типа данных:

Type Ttree=^Tre

Tre=Record