<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=54278&amp;view=findpost&amp;p=380027</guid>
        <pubDate>Sun, 13 Jun 2004 19:26:02 +0000</pubDate>
        <title>Линейные структуры данных</title>
        <link>https://forum.sources.ru/index.php?showtopic=54278&amp;view=findpost&amp;p=380027</link>
        <description><![CDATA[Gazon: <span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='13' style='font-size:13pt;'>Стеки</span></span><br>
<br>
Организация стека в определенном смысле противоположна организации очереди, поскольку здесь используется доступ по принципу &quot;последней пошел, первый вышел&quot; (такой метод доступа иногда называют методом <strong class='tag-b'>LIFO</strong> ). Представим себе стопку тарелок. Нижняя тарелка из этой стопки будет использована последней, а верхняя тарелка (которая была установлена в стопку последней) будет использована первой. Стеки широко используются в системном программном обеспечении, включая компиляторы и интерпретаторы.<br>
Исторически сложилось так, что две основные операции для стека - поместить в стек и выбрать из стека - получили название соответственно &quot;затолкнуть&quot; и &quot;вытолкнуть&quot;. Поэтому для реализации стека необходимо создать две функции: &quot;<strong class='tag-b'>push</strong>&quot; (затолкнуть), которая помещает элемент в вершину стека, и &quot;<strong class='tag-b'>pop</strong>&quot; (вытолкнуть), которая выбирает из вершины стека значение.<br>
Необходимо также предусмотреть определенную область в памяти, где фактически будет храниться стек. Для этого можно использовать массив или можно выделить область памяти, используя средство динамического распределения памяти, предусмотренное в языке Турбо Паскаль. Как и при работе с очередью при выборке значения из стека элемент будет потерян, если его не сохранить где-нибудь в памяти.<br>
Ниже приводится общая форма процедур установки в стек и выборки из стека.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Const </div><div class="code_line">&nbsp;&nbsp;MAX = 100;</div><div class="code_line">&nbsp;</div><div class="code_line">Var </div><div class="code_line">&nbsp;&nbsp;stack: array [1..100] Of integer;</div><div class="code_line">&nbsp;&nbsp;tos: integer; {помещение объекта в стек}</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure Push (i:integer);</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;If tos&#62;=MAX Then WriteLn(&#39;Стек пуст&#39;)</div><div class="code_line">&nbsp;&nbsp;Else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;stack[tos] := i;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;tos := tos+1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;End;</div><div class="code_line">End; {конец процедуры помещения объекта в стек}</div><div class="code_line">{ выборка объекта из стека }</div><div class="code_line">&nbsp;</div><div class="code_line">Function Pop: integer;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;tos := tos-1;</div><div class="code_line">&nbsp;&nbsp;If tos&#60;1 Then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;WriteLn(&#39;Стек переполнен&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;tos := tos+1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Pop := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;End</div><div class="code_line">&nbsp;&nbsp;Else Pop := stack[tos];</div><div class="code_line">End;{конец функции выборки объекта из стека}</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script><br>
<br>
Переменная &quot;tos&quot; содержит значение индекса для следующего помещаемого в стек элемента. При реализации этих процедур никогда нельзя забывать о проверке ситуаций переполнения стека и выборки из пустого стека. В приведенных процедурах нулевое значение указателя &quot;tos&quot; означает, что стек пуст, а значение этого указателя, равное или превышающее адрес последней ячейки памяти, где содержится стек, означает заполнение стека. Рис.7 иллюстрирует работу стека.<br>
<br>
<pre><strong class='tag-b'>Операция         <span class="tag-color tag-color-named" data-value="blue" style="color: blue">Содержимое стека</span></strong>
Push (A)                 <span class="tag-color tag-color-named" data-value="blue" style="color: blue">A</span>
Push (В)                 <span class="tag-color tag-color-named" data-value="blue" style="color: blue">B A</span>
Push (С)                 <span class="tag-color tag-color-named" data-value="blue" style="color: blue">C B A</span>
Pop, выбирается С        <span class="tag-color tag-color-named" data-value="blue" style="color: blue">В А</span>
Push(F)                  <span class="tag-color tag-color-named" data-value="blue" style="color: blue">F B A</span>
Pop, выбирается F        <span class="tag-color tag-color-named" data-value="blue" style="color: blue">B A</span>
Pop, выбирается В        <span class="tag-color tag-color-named" data-value="blue" style="color: blue">А</span>
Рор, выбирается А        <span class="tag-color tag-color-named" data-value="blue" style="color: blue">пусто</span></pre><br>
<br>
Рис.7. Работа стека.<br>
<br>
Хорошим примером применения стека является калькулятор, который может выполнять четыре действия. Большинство калькуляторов используют стандартную форму выражений, которая носит название инфиксной формы. В общем виде ее можно представить в виде &quot;операнд-оператор-операнд&quot;.<br>
Например, для прибавления 100 к 200 вы должны ввести число 100, набрать символ сложения, ввести число 200 и нажать клавишу со знаком равенства. Однако, некоторые каль- куляторы применяют другую форму выражений, получившую название постфиксной формы. В этом случае оба операнда вводятся перед вводом оператора. Например, для добавления 100 к 200 при использовании постфиксной формы сначала вводится число 100, затем вводится число 200 и после этого нажимается клавиша со знаком плюс. Введенные операнды помещаются в стек. При вводе оператора из стека выбираются два операнда и результат помещается в стек. При использовании постфиксной формы очень сложные выражения могут легко вычисляться на калькуляторе.<br>
<br>
Ниже показана программа для такого калькулятора.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">{калькулятор с четырьмя операциями, иллюстрирующий работу}</div><div class="code_line">&nbsp;</div><div class="code_line">Program four_function_calc;</div><div class="code_line">&nbsp;</div><div class="code_line">Const </div><div class="code_line">&nbsp;&nbsp;MAX = 100;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;</div><div class="code_line">Var </div><div class="code_line">&nbsp;&nbsp;stack: array [1..100] Of integer;</div><div class="code_line">&nbsp;&nbsp;tos: integer;{указатель вершины стека}</div><div class="code_line">&nbsp;&nbsp;a, b: integer;</div><div class="code_line">&nbsp;&nbsp;s: string[80];</div><div class="code_line">{поместить объект в стек}</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure Push(i:integer);</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;If tos &#62;= MAX Then Writeln(&#39;Стек полон&#39;)</div><div class="code_line">&nbsp;&nbsp;Else</div><div class="code_line">&nbsp;&nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;stack[tos] := 1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;tos := tos+1;</div><div class="code_line">&nbsp;&nbsp; &nbsp;End;</div><div class="code_line">End;{Push}</div><div class="code_line">{выборка объекта из стека}</div><div class="code_line">&nbsp;</div><div class="code_line">Function Pop: integer;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp;tos := tos-1;</div><div class="code_line">&nbsp;&nbsp;If tos &#60; 1 Then</div><div class="code_line">&nbsp;&nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Writeln(&#39;Стек переполнен&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;tos := tos+1;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Pop := 0;</div><div class="code_line">&nbsp;&nbsp; &nbsp;End</div><div class="code_line">&nbsp;&nbsp;Else Pop := stack[tos];</div><div class="code_line">End;{Pop}</div><div class="code_line">Begin{калькулятор}</div><div class="code_line">&nbsp;&nbsp;tos := 1;</div><div class="code_line">&nbsp;&nbsp;Writeln(&#39;For Function Calculator&#39;);</div><div class="code_line">&nbsp;&nbsp;Repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp;Write(&#39;: &#39;); { вывод приглашения }</div><div class="code_line">&nbsp;&nbsp; &nbsp;Readln(s);</div><div class="code_line">&nbsp;&nbsp; &nbsp;Val(s, a, b); { преобразование строки символов в целое число }</div><div class="code_line">{ считается, что при успешном преобразовании пользователь ввел число,</div><div class="code_line">&nbsp;а в противном случае пользователь ввел оператор}</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp;If (b=0) And ((Length(s)&#62;1) Or (s[1]&#60;&#62;&#39;-&#39;)) Then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Push(a)</div><div class="code_line">&nbsp;&nbsp; &nbsp;Else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Case s[1] Of</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&#39;+&#39;:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Writeln(a+b);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Push(a+b);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&#39;-&#39;:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Writeln(b+a);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Push(b+a);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&#39;*&#39;:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Writeln(a*b);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Push(a*b);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&#39;/&#39;:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;b := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If a=0 Then Writeln(&#39;делим на ноль&#39;)</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Else</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Writeln(b Div a);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Push(b Div a);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;&#39;.&#39;:</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;a := Pop;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Writeln(a);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Push(a);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp;Until UpCase(s[1])=&#39;G&#39;;</div><div class="code_line">End.</div></ol></div></div></div></div><br>
Для того, чтобы посмотреть, что находится в вершине стека, достаточно ввести точку. Хотя данная программа выполняет арифметические действия только с целыми числами, ее легко можно приспособить для чисел с плавающей запятой, изменяя тип данных стека и преобразуя оператор &quot;div&quot; в оператор деления для чисел с плавающей запятой (наклонная черта).]]></description>
        <author>Gazon</author>
        <category>Pascal: Структуры данных</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=54278&amp;view=findpost&amp;p=368554</guid>
        <pubDate>Sat, 29 May 2004 09:37:43 +0000</pubDate>
        <title>Линейные структуры данных</title>
        <link>https://forum.sources.ru/index.php?showtopic=54278&amp;view=findpost&amp;p=368554</link>
        <description><![CDATA[romtek: <strong class='tag-b'><span class="tag-color tag-color-named" data-value="blue" style="color: blue"><span class='tag-size' data-value='11' style='font-size:11pt;'>Пример работы со стеком.</span></span></strong><br>
<br>
Вводятся положительные числа. Введение отрицательного числа означает конец ввода данных.<ol class="tag-list" type="1"><li>Ввод чисел</li><li>Выводится стек в обратном порядке введения чисел</li><li>Выводится отсортированный стек</li><li>Удаляются все элементы стека</li></ol><div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">program StackStuff;</div><div class="code_line">&nbsp;</div><div class="code_line">type PItem = ^stack;</div><div class="code_line">&nbsp;&nbsp; &nbsp; stack = record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; Value: integer;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; next : PItem;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">var</div><div class="code_line">&nbsp;&nbsp; top &nbsp;: PItem;</div><div class="code_line">&nbsp;&nbsp; count: word;</div><div class="code_line">&nbsp;</div><div class="code_line">function Correct(var num: integer): boolean; { To check condition }</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; readln(num);</div><div class="code_line">&nbsp;&nbsp; &nbsp; Correct := (Num&#62;=0);</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure FillStack(var P: PItem);</div><div class="code_line">var last: PItem;</div><div class="code_line">&nbsp;&nbsp; &nbsp;v: integer;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; P:=Nil;</div><div class="code_line">&nbsp;&nbsp; &nbsp; count:=0;</div><div class="code_line">&nbsp;&nbsp; &nbsp; while Сorrect(v) do</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;New(last);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;last^.next:=P;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;last^.Value:=v;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;P:=last;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;inc(count); { increase count of elements }</div><div class="code_line">&nbsp;&nbsp; &nbsp; end;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure SortStack(P: PItem);</div><div class="code_line">Var</div><div class="code_line">&nbsp;Q &nbsp; &nbsp;: PItem;</div><div class="code_line">&nbsp;T &nbsp; &nbsp;: Integer;</div><div class="code_line">&nbsp;Done : Boolean;</div><div class="code_line">&nbsp;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; Repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Done := True;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Q := P;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; While Q^.Next &#60;&#62; Nil Do</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;If Q^.Value &#62; Q^.Next^.Value Then</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { Change values }</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; T := Q^.Value;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Q^.Value := Q^.Next^.Value;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Q^.Next^.Value := T;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Done := False;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Q := Q^.Next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End;</div><div class="code_line">&nbsp;&nbsp; &nbsp; Until Done;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure ViewStack(P: PItem);</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; write(&#39;Stack values: &#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; if P = Nil then</div><div class="code_line">&nbsp;&nbsp; &nbsp; begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;write(&#39;stack is empty.&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;exit;</div><div class="code_line">&nbsp;&nbsp; &nbsp; end</div><div class="code_line">&nbsp;&nbsp; &nbsp; else</div><div class="code_line">&nbsp;&nbsp; &nbsp; { start from last element }</div><div class="code_line">&nbsp;&nbsp; &nbsp; repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; write(P^.Value : 8);</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; P := P^.next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; until P = Nil;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">procedure Del_All (var P: PItem); { Deleting of All stack elements }</div><div class="code_line">var Last: PItem;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; repeat</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Last := P;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; P := P^.next;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dispose (Last);</div><div class="code_line">&nbsp;&nbsp; &nbsp; until P = Nil;</div><div class="code_line">end;</div><div class="code_line">&nbsp;</div><div class="code_line">begin</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln (#13#10&#39;Enter positive number (negative to finish)&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; FillStack (Top);</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln (#13#10&#39;The stack consist of &#39;,count,&#39; numbers.&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; ViewStack (Top);</div><div class="code_line">&nbsp;&nbsp; &nbsp; readln;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln (#13#10&#39;--Sorted stack--&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; SortStack (Top);</div><div class="code_line">&nbsp;&nbsp; &nbsp; ViewStack (Top);</div><div class="code_line">&nbsp;&nbsp; &nbsp; readln;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; writeln (#13#10&#39;Deleting stack...&#39;);</div><div class="code_line">&nbsp;&nbsp; &nbsp; Del_All (Top);</div><div class="code_line">&nbsp;&nbsp; &nbsp; ViewStack (Top);</div><div class="code_line">&nbsp;&nbsp; &nbsp; readln;</div><div class="code_line">end.</div></ol></div></div></div></div>]]></description>
        <author>romtek</author>
        <category>Pascal: Структуры данных</category>
      </item>
	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=54278&amp;view=findpost&amp;p=358916</guid>
        <pubDate>Sat, 15 May 2004 13:44:52 +0000</pubDate>
        <title>Линейные структуры данных</title>
        <link>https://forum.sources.ru/index.php?showtopic=54278&amp;view=findpost&amp;p=358916</link>
        <description><![CDATA[tserega: <span class='tag-size' data-value='21' style='font-size:21pt;'><span class="tag-color tag-color-named" data-value="blue" style="color: blue">Линейные структуры данных на примере динамических списков</span></span><br>
<br>
Все структры данных можно классифицировать по нескольким категориям:<ul class="tag-list"><li> линейность (линейные - стеки, очереди; нелинейные - графы, деревья)</li><li> связанность (нужно ли физически хранить ссылки на следующий элемент(ы))</li><li> по количеству элементов:<br>
 <ul class="tag-list"><li> статистические - количество элементов строго фиксировано<br>
 </li><li> частично динамические - количество элементов может меняться, но не превосходит некоторго максимума<br>
 </li><li> динамические - количество элементов может быть произвольным</li></ul></li></ul><br>
Рассмотрим примеры реализации динамических линейных связанных структур данных. Прежде всего, советую ознакомиться с этой статьей: <a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=50681' target='_blank'>Указатели (Pointers)</a><br>
Замечание: во преки расхожему мнению, список не является структурой данных. Это всего лишь идея, метод решения. На основе списка построены настоящие структуры данных - стеки (stack), очереди(queue), дэки (double-ended queue), кольца (ring).<br>
<br>
Во всех примерах для реализации списка будет использована такая структура:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type PElement = ^TElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; TElement = Record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Data : Longint; {данные - целое число}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Next : PElement; {указатель на следующий элемент}</div><div class="code_line">&nbsp;&nbsp; &nbsp; End;</div></ol></div></div></div></div><br>
<br>
<span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="purple" style="color: purple">Стек</span></span><br>
Самый простой представитель динамических структур. Представьте себе большую стопку книг. Понятно, что мы не можем достать книгу из самого низа. Для этого требуется снять все книги, которые лежат выше. Такую структуру называют LIFO (Last In - First Out). <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type PElement = ^TElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; TElement = Record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Data : Longint;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Next : PElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; End;</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure Push(X : Longint; Var S : PElement); {добавление элемента на вершину стека}</div><div class="code_line">Var P : PElement;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;P:=New(PElement); {создаем временный элемент}</div><div class="code_line">&nbsp;P^.Data:=X; {присваиваем ему необходимое значение}</div><div class="code_line">&nbsp;P^.Next:=S; {следующий элемент будет уже готовый стек}</div><div class="code_line">&nbsp;S:=P; {а вершина стека - только что созданный элемент}</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">Function Pop(Var X : Longint; Var S : PElement) : Boolean; {взятие элемента с вершины стека}</div><div class="code_line">Var P : PElement;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;If (S = Nil) Then {если стек путой, то возвращать нечего}</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; X:=0;</div><div class="code_line">&nbsp;&nbsp; Pop:=False;</div><div class="code_line">&nbsp;&nbsp;End Else</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; X:=S^.Data; {запомним значение на вершине стека}</div><div class="code_line">&nbsp;&nbsp; P:=S;</div><div class="code_line">&nbsp;&nbsp; S:=S^.Next; {переместим вершину стека на следующий элемент}</div><div class="code_line">&nbsp;&nbsp; Dispose(P); {уничтожим вытащенный элемент}</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">{Пример реализации}</div><div class="code_line">Var Stack : PElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp;X : Longint;</div><div class="code_line">&nbsp;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;Stack:=Nil;</div><div class="code_line">&nbsp;Push(5, Stack);</div><div class="code_line">&nbsp;Push(13, Stack);</div><div class="code_line">&nbsp;Push(2, Stack);</div><div class="code_line">&nbsp;Push(6, Stack);</div><div class="code_line">&nbsp;Push(20, Stack);</div><div class="code_line">&nbsp;While (True) Do</div><div class="code_line">&nbsp;&nbsp;If Pop(X, Stack) Then Writeln(X) Else Break;</div><div class="code_line">End.</div></ol></div></div></div></div><br>
Стек - &quot;родная&quot; конструкция для процедурных языков программирования. Каждый вызов процедуры или функции идет через стек (точнее, в стек записывается адрес, с которого вызвали данную функцию).<br>
Например:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">procedure A;</div><div class="code_line">begin</div><div class="code_line">...</div><div class="code_line">end;</div><div class="code_line">procedure B;</div><div class="code_line">begin</div><div class="code_line">...</div><div class="code_line">A;</div><div class="code_line">...</div><div class="code_line">end;</div><div class="code_line">...</div><div class="code_line">B;</div><div class="code_line">...</div></ol></div></div></div></div><br>
В стек сначала запишется адрес процедуры B, тотом на вершину добавится адрес процедуры A. После выполнения процедуры A ее адрес будет удален из стека. После окончания работы процедуры B ее адрес также будет удален из стека.<br>
Стеком также удобно сделать проверку корректности скобочного выражения: <a class='tag-url' href='http://forum.sources.ru/index.php?showtopic=42035' target='_blank'>Анализ скобочной структуры</a><br>
<br>
<span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="purple" style="color: purple">Очередь</span></span><br>
Название структуры соответсвует ее смыслу. Представьте себе очередь (не толпу&#33;) людей. Тот, кто первый пришел, первый и выйдет. Часто очередь называют струкурой FIFO (First In - First Out). В отличии от стека, где добавление и извлечение элементов происходит с одного конца, здесь доавление и удаление происходит с разных концов. Поэтому будем хранить указатели на первый и последний элементы.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type PElement = ^TElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; TElement = Record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Data : Longint;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Next : PElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; End;</div><div class="code_line">&nbsp;</div><div class="code_line">&nbsp;&nbsp; &nbsp; TQueue = Record {сама очередь}</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;First, Last : PElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; End;</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure Add(X : Longint; Var Q: TQueue); {добавление элемента в очередь}</div><div class="code_line">Var P : PElement;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;If (Q.Last = Nil) Then {если очерель пуста, то добавленный элемент будет одновременно первым и последним}</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; Q.Last:=New(PElement); {создаем элемент}</div><div class="code_line">&nbsp;&nbsp; Q.First:=Q.Last; {он же первый и последний одновременно}</div><div class="code_line">&nbsp;&nbsp; Q.Last^.Data:=X;</div><div class="code_line">&nbsp;&nbsp; Q.Last^.Next:=Nil; {следующего элемента пока нет}</div><div class="code_line">&nbsp;&nbsp;End Else</div><div class="code_line">&nbsp;&nbsp;Begin {в очереди уже есть элементы}</div><div class="code_line">&nbsp;&nbsp; P:=New(PElement); {создаем элемент}</div><div class="code_line">&nbsp;&nbsp; P^.Data:=X; </div><div class="code_line">&nbsp;&nbsp; P^.Next:=Nil;</div><div class="code_line">&nbsp;&nbsp; Q.Last^.Next:=P;</div><div class="code_line">&nbsp;&nbsp; Q.Last:=P; {добавляем его в конец очереди}</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">Function Get(Var X : Longint; Var Q : TQueue) : Boolean; {извлечение элемента}</div><div class="code_line">Var P : PElement;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;If (Q.First = Nil) Then {если очерель пустая, то извлекать нечего}</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; X:=0;</div><div class="code_line">&nbsp;&nbsp; Get:=False;</div><div class="code_line">&nbsp;&nbsp;End Else</div><div class="code_line">&nbsp;&nbsp;Begin {иначе будем брать первый элемент}</div><div class="code_line">&nbsp;&nbsp; X:=Q.First^.Data; {запомним его значение}</div><div class="code_line">&nbsp;&nbsp; P:=Q.First; </div><div class="code_line">&nbsp;&nbsp; Q.First:=Q.First^.Next; {перейдем на следующий}</div><div class="code_line">&nbsp;&nbsp; Dispose(P); {уничтожим запомненный}</div><div class="code_line">&nbsp;&nbsp; Get:=True;</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">{Пример реализации}</div><div class="code_line">Var Q : TQueue;</div><div class="code_line">&nbsp;&nbsp; &nbsp;X : Longint;</div><div class="code_line">&nbsp;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;Add(5, Q);</div><div class="code_line">&nbsp;Add(6, Q);</div><div class="code_line">&nbsp;Add(7, Q);</div><div class="code_line">&nbsp;Add(8, Q);</div><div class="code_line">&nbsp;While (True) Do</div><div class="code_line">&nbsp;&nbsp;If Get(X, Q) Then Writeln(X) Else Break;</div><div class="code_line">End.</div></ol></div></div></div></div><br>
<br>
<span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="purple" style="color: purple">Двусвязанный список</span></span><br>
По идее двусвязанный список очень похож на обычный список. Единственное отличие - наличие ссылок на предыдущий элемент. Поэтому немного изменятся процедуры добаления и извлечения элементов.<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type PElement = ^TElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; TElement = Record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Data : Longint;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Next, Prev : PElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; End;</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure AddAfter(X : Longint; Var L : PElement); {добавление в НЕПУСТОЙ список}</div><div class="code_line">Var P : PElement;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;P:=New(PElement); {создаем элемент}</div><div class="code_line">&nbsp;P^.Data:=X;</div><div class="code_line">&nbsp;If (L^.Next = Nil) Then {надо добавить элемент в конец списка}</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; L^.Next:=P;</div><div class="code_line">&nbsp;&nbsp; P^.Prev:=L;</div><div class="code_line">&nbsp;&nbsp; P^.Next:=Nil;</div><div class="code_line">&nbsp;&nbsp;End Else</div><div class="code_line">&nbsp;&nbsp;Begin {надо вставить элемент между двумя}</div><div class="code_line">&nbsp;&nbsp; P^.Next:=L^.Next;</div><div class="code_line">&nbsp;&nbsp; L^.Next^.Prev:=P;</div><div class="code_line">&nbsp;&nbsp; P^.Prev:=L;</div><div class="code_line">&nbsp;&nbsp; L^.Next:=P;</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">{Пример реализации}</div><div class="code_line">Var L, P : PElement;</div><div class="code_line">&nbsp;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;L:=Nil;</div><div class="code_line">&nbsp;L:=New(PElement); L^.Next:=Nil; L^.Prev:=Nil; L^.Data:=0; {создаем первый элемент}</div><div class="code_line">&nbsp;AddAfter(7, L);</div><div class="code_line">&nbsp;AddAfter(5, L);</div><div class="code_line">&nbsp;L:=L^.Next;</div><div class="code_line">&nbsp;AddAfter(3, L);</div><div class="code_line">&nbsp;While L^.Next &#60;&#62; Nil Do L:=L^.Next;</div><div class="code_line">&nbsp;While L &#60;&#62; Nil Do</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; Writeln(L^.Data);</div><div class="code_line">&nbsp;&nbsp; P:=L;</div><div class="code_line">&nbsp;&nbsp; L:=L^.Prev;</div><div class="code_line">&nbsp;&nbsp; Dispose(P);</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">End.</div></ol></div></div></div></div><br>
<br>
<span class='tag-size' data-value='14' style='font-size:14pt;'><span class="tag-color tag-color-named" data-value="purple" style="color: purple">Кольцо</span></span><br>
Если в списке ссылка последнего элемента указывает на первый, то такой список называют зацикленным (циклическим, или просто кольцом). Понятно, что у такого списка нет ни начала, ни конца. Чтобы определить &quot;начальный&quot; элемент, часто создают элемент, которому приписано специальное значение (например, если это список букв, то элому элементу можно присвоить значение #0, т.е. символ с кодом 0). Тогда такой циклический список называют кольцом с замком. <br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Type PElement = ^TElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; TElement = Record</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Data : Longint;</div><div class="code_line">&nbsp;&nbsp; &nbsp; &nbsp;Next : PElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp; End;</div><div class="code_line">&nbsp;</div><div class="code_line">Procedure Add(X : Longint; Var R : PElement); {добавление элемента в кольцо, эквивалентно вставки элемента между двумя}</div><div class="code_line">Var P : PElement;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;P:=New(PElement);</div><div class="code_line">&nbsp;P^.Data:=X;</div><div class="code_line">&nbsp;P^.Next:=R^.Next;</div><div class="code_line">&nbsp;R^.Next:=P;</div><div class="code_line">End;</div><div class="code_line">&nbsp;</div><div class="code_line">{Пример реализации}</div><div class="code_line">Var R, P : PElement;</div><div class="code_line">&nbsp;&nbsp; &nbsp;I : Longint;</div><div class="code_line">&nbsp;</div><div class="code_line">Begin</div><div class="code_line">&nbsp;R:=New(PElement); R^.Data:=0; R^.Next:=R;</div><div class="code_line">&nbsp;For I:=1 To 4 Do</div><div class="code_line">&nbsp;&nbsp;Add(I, R);</div><div class="code_line">&nbsp;I:=0;</div><div class="code_line">&nbsp;{два раза выведем список}</div><div class="code_line">&nbsp;While (I &#60; 3) Do</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; If R^.Data = 0 Then Inc(I) Else Writeln(R^.Data);</div><div class="code_line">&nbsp;&nbsp; R:=R^.Next;</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">&nbsp;{уничнтожение списка связано с маленьким фокусом: преобразуем колько в линейный список}</div><div class="code_line">&nbsp;P:=R; {&quot;разорвем&quot; список на одном из элементов}</div><div class="code_line">&nbsp;R:=R^.Next;</div><div class="code_line">&nbsp;P^.Next:=Nil;</div><div class="code_line">&nbsp;{уничтожим как обычный список}</div><div class="code_line">&nbsp;While R &#60;&#62; Nil Do</div><div class="code_line">&nbsp;&nbsp;Begin</div><div class="code_line">&nbsp;&nbsp; P:=R;</div><div class="code_line">&nbsp;&nbsp; R:=R^.Next;</div><div class="code_line">&nbsp;&nbsp; Dispose(P);</div><div class="code_line">&nbsp;&nbsp;End;</div><div class="code_line">End.</div></ol></div></div></div></div>]]></description>
        <author>tserega</author>
        <category>Pascal: Структуры данных</category>
      </item>
	
      </channel>
      </rss>
	