Шаг 22.
Дек

    На этом шаге мы рассмотрим создание и основные операции над деками.

    Дек ("двухсторонняя очередь") на базе однонаправленного линейного списка - список магазинного типа на базе однонаправленного линейного списка, в котором все включения и исключения звеньев делаются на обеих концах очереди.

    Мы приведем лишь демонстрационный пример.


    Пример. Формирование дека, просмотр его содержимого, добавление элемента к деку и удаление элемента из дека.
#include<iostream.h>
struct node
{
  int elem;
  node *sled;
};
class Spisok
{
  private:
    node *ld,*rd;
    int el_left,el_right;
  public:
    void POSTROENIE ();
    void VYVOD ();
    void VSTAV1 (int);
    void VSTAV2 (int);
    int SetElLeft() {return el_left;}
    int SetElRight() {return el_right;}
    void YDALE1 ();
    void YDALE2 ();
    void OCHISTKA();
};

void main ()
{
  Spisok A;
  int el;
		
  A.POSTROENIE (); A.VYVOD ();
  cout<<"Добавим звено справа.\n";
  cout<<"Введите элемент добавляемого звена: ";
  cin>>el;
  A.VSTAV1 (el); A.VYVOD ();
  cout<<"Добавим звено слева.\n";
  cout<<"Введите элемент добавляемого звена: ";
  cin>>el;
  A.VSTAV2 (el); A.VYVOD ();
  cout<<"Удалим звено справа.\n";
  A.YDALE1 (); A.VYVOD (); cout<<A.SetElRight()<<endl;
  cout<<"Удалим зввено слева.\n";
  A.YDALE2 (); A.VYVOD (); cout<<A.SetElLeft()<<endl;
  A.OCHISTKA();
}

void Spisok::POSTROENIE ()
//Построение дека :
// ld - указатель на левый конец дека,
// rd - Указатель на правый конец дека.
{
  node *k;
  int el;
		
  cout<<"Вводите содержимое звеньев дека: \n";
  cin>>el;
  if  (el!=0)
  {
    k = new (node);
    (*k).elem = el; (*k).sled = NULL;
    ld = k; rd = k; cin>>el;
    while  (el!=0)
      {VSTAV1 (el); cin>>el;}
  }
  else
    {rd = NULL; ld = NULL;}
}

void Spisok::VYVOD ()
//Вывод содержимого дека:
// ld - указатель на левый конец дека.
{
  node *k;

  k = ld; cout<<"Дек: ";
  while  (k!=NULL)
    {cout<<(*k).elem<<" "; k = (*k).sled;}
  cout<<endl;
}
  
void Spisok::VSTAV1 (int el)
// Помещение звена, содержащего элемент el, в дек справа.
// ld - указатель на левый конец дека,
// rd - указатель на правый конец дека.
{
  node *k;

  k = new (node);
  (*k).elem = el; (*k).sled = NULL;
  if  (rd!=NULL)
    {(*rd).sled = k; rd = k;}
  else
    {rd = k; ld = k;}
}

void Spisok::VSTAV2 (int el)
//Помещение звена, содержащего элемент el, в дек слева.
// ld - указатель на левый конец дека,
// rd - указатель на правый конец дека.
{
  node *k;

  k = new (node);
  (*k).elem = el; (*k).sled = ld;
  if  (ld!=NULL) ld = k;
  else  {ld = k; rd = k;}
}
  
void Spisok::YDALE1 ()
//Удаление звена из дека справа
//с сохранением удаляемого звена в переменной el_right.
// ld - указатель на левый конец дека,
// rd - указатель на правый конец дека.
{
  node *z;
  node *k;

  if  (rd==ld)
  {
    el_right = (*rd).elem; delete rd;
    ld = rd = NULL; cout<<"Дек пуст!\n";
  }
  else
  {
    z = ld; k = (*ld).sled;
    while  (k!=rd)
      {z = k; k = (*k).sled;}
    el_right = (*rd).elem; (*z).sled = NULL; delete rd;
    rd = z;
  }
}

void Spisok::YDALE2 ()
// Удаление звена из дека слева 
// с сохранением удаляемого звена в переменной el_left.
// ld - указатель на левый конец дека,
// rd - указатель на правый конец дека.
{
  node *q;

  if  (ld!=NULL)
  {
    el_left = (*ld).elem; q = ld;
    ld = (*ld).sled; delete q;
  }
  else  cout<<"Дек пуст!\n";
}

void Spisok::OCHISTKA()
{
  node *k,*q;

  k = ld;
  if (k!=NULL)
  {
    q = (*k).sled;
    while  (q!=NULL)
      {delete k; k = q; q=(*k).sled;}
  delete k;
  }
}
Текст этой программы можно взять здесь.

    Со следующего шага мы начнем рассматривать линейные двунаправленные списки.




Предыдущий шаг Содержание Следующий шаг