Лекция 3: Последовательности (связанное распределение, стеки и очереди)
Стеки и очередь
В комбинаторных алгоритмах особую важность представляют две структуры данных, основанные на динамических последовательностях, т.е. последовательностях, которые изменяются вследствие включения новых и исключения имеющихся элементов. В обоих случаях операции включения и исключения, которым подвергается последовательность, имеют ограниченный вид: они производятся только в концах последовательности. Стек есть последовательность, у которой все включения и исключения происходят только в ее правом конце, называемом вершиной стека (соответственно, левый конец последовательности называется основанием ). Таким образом, элементы включаются в стек и исключаются из него в соответствии с правилом "Первым пришел - последним ушел ". Очередь - это последовательность, в которой все включения производятся на правом конце списка ( в конце очереди ), в то время как все исключения производятся на левом конце ( в начале очереди ). В противоположность стеку очередь оперирует в режиме " Первым пришел - первым ушел ".
Стеки и очереди имеют важное значение. Для выполнения какой-либо определенной задачи может потребоваться выполнение ряда подзадач. Каждая подзадача может также привести к другим требующим выполнения подзадачам. И стеки, и очереди являются механизмом, посредством которого запоминаются подзадачи, подлежащие выполнению, а также порядок, в котором они должны быть выполнены. В некоторых случаях порядок таков: " Первым пришел - последним ушел "; тогда удобно использовать стеки. Если порядок подчиняется правилу " Первым пришел - первым ушел ", то подходящим инструментом являются очереди.
Задачи
Задача 1. Создать список, элементами которого являются числа: 1 2 3 4 5 6 7 8 9. Вывести список на экран терминала. Включить в связанный список элемент 2005 после каждого элемента, который делится на 3. Модифицированный список вывести на экран терминала.
Задача 2. Очередью с приоритетом называется линейный список, который оперирует в режиме "первым включается - с высшим приоритетом исключается"; иными словами, каждому элементу очереди сопоставлено некоторое число - приоритет. Включения производятся в конец очереди, а исключения - в любом месте очереди, поскольку исключаемый элемент - это всегда элемент с высшим приоритетом. Нужно описать алгоритм (и его реализацию) включения и исключения для очередей с приоритетом.
Программы
Программа 1. Создание списка.
// Алгоритм реализован на языке программирования Turbo-C++.
#include <stdio.h>
#include <conio.h>
#include <dos.h>
struct List{int i;
List*next;
};
List*head=NULL;
void Hed(int i)
{if(head==NULL){head=new List;
head->i=1;
head->next=NULL;
}else
{
struct List*p,*p1;
p=head;
while(p->next!=NULL)
p=p->next;
p1=new List;
p1->i=i;
p1->next=NULL;
p->next=p1;
}
}
int s=0;
void Print(List*p)
{cprintf(" %d",p->i);
if(p->next!=NULL)Print(p->next);
}
void delist()
{List*p;
while(head!=NULL)
{p=head;
head=head->next;
delete(p);
}
}
void Vstavka(int i1,int c)
{List*p=head,*p1;
while(p->i!=i1)
p=p->next;
p1=new List;
p1->i=c;
p1->next=p->next;
p->next=p1;
}
void main()
{
clrscr();
for(int i=1;i<=10;i++)
Hed(i);
textcolor(12);
Print(head);
textcolor(1);
Vstavka(10,11);
printf("\n");
Print(head);
textcolor(11);
Vstavka(3,12);
printf("\n");
Print(head);
textcolor(14);
Vstavka(5,13);
printf("\n");
Print(head);
delist();
getch();
}Программа 2. Создание стека и работа со стеком.
//Работа со стеком
// Алгоритм реализован на языке программирования Turbo-C++.
#include <stdio.h>
#include <dos.h>
#include <iostream.h>
#include <PROCESS.H>
#include <STDLIB.H>
#include <conio.H>
#define max_size 200
// char s[max_size]; //компоненты стека
int s[max_size];
int next=0; // позиция стека
int Empty()
{
return next==0;
}
int Full()
{
return next==max_size;
}
void Push()
{ if (next==max_size)
{
cout <<"Ошибка: стек полон"<<endl;}
else { next++;cout <<"Добавлен"<<endl;
cout <<"Что поместить в стек?"<<endl;
cin <<s[next-1];
}
}
void OUTst()
{int i=0;
if (next==0)
{
cout <<"Cтек пуст"<<endl;}
else { for(i=0;i <next;i++)
cout <<s[i] <<"" <<endl;
}
}
void Clear()
{
next=0;
}
Poz()
{
return next;
}
void Del()
{
int a;
if (next==0) cout <<"Ошибка: стек пуст" <<endl; else
{next--;cout <<"Удален" <<endl;}
}
void menu(){
cout <<"0: распечатать стек" <<endl;
cout <<"1: добавить в стек" <<endl;
cout <<"2: удалить из стека" <<endl;
cout <<"3: узнать номер позиции в стеке" <<endl;
cout <<"4: узнать, пуст ли стек" <<endl;
cout <<"5: узнать, полон ли стек" <<endl;
cout <<"6: очистить стек" <<endl;
cout <<"7: выход" <<endl;
}
main()
{
char c;
clrscr();
textcolor(11);
do {
menu();
cin"c;
clrscr();
switch (c) {
case "0":OUTst();getch();break;
case "1":Push();break;
case "2":Del();getch();break;
case "3":cout <<"Hомер" <<Poz() <<endl;getch();break;
case "4":if (Empty()==1) cout <<"Пуст" <<endl; else cout <<"Hе
пуст" <<endl;getch();break;
case '5':if (Full()==1)cout <<"Полон" <<endl; else cout <<"Hе
полон" <<endl;getch();break;
case '6':Clear();cout <<"Стек очищен" <<endl;getch();break;
case '7':exit(1);
}
delay(200);
}
while (c!=7);
return 0;
}