ОСНОВЫ ПРОГРАММНОГО
  КОНСТРУИРОВАНИЯ
                  Лекция № 5
              19 марта 2013 г.
СОСТАВНЫЕ ТИПЫ ДАННЫХ
ЗАПИСИ

• Объединяют  разнотипные данные, относящиеся к одному
 объекту из предметной области.

    struct Point {          struct Order {
        double x, y, z;         struct User *user;
    };                          struct Date date;
                                int nitems;
    struct Planet {             struct OrderItem *items;
        const char *name;   };
        double mass;
        double radius;
        /* .... */
    };
МАССИВЫ

• Множество   однотипных данных:

 • Набор   временных отсчетов.

 • Векторы   и матрицы.

 • Набор   строк.

• Элементы   массива хранятся в смежных ячейках памяти.
ОДНОМЕРНЫЙ МАССИВ

• A0   – адрес начала массива.

•s   – размер элемента массива.

• Чему   равен A(n) – адрес n-го элемента массива?
                          int a[5];

                Индекс   0       1   2   3   4
                Адрес    A0      ?   ?   ?   ?
ОДНОМЕРНЫЙ МАССИВ



 A(n) = A0 + n⋅s
ДВУМЕРНЫЙ МАССИВ
                   int a[2][3];

     С-style           или        FORTRAN-style
          k                               k

     0    1    2                      0   2      4
m                                 m
     3    4    5                      1   3      5


    n = 3m+k         a[m][k]          n = 2k+m
N-МЕРНЫЙ МАССИВ


•K   размерностей: A[NK][NK-1]....[N1].

• А(nK, nK-1, …, n1)   = A0 + s⋅n(nK, nK-1, …, n1).

• n(nK, nK-1, …, n1)   =?
C-STYLE

• Уменьшаем порядок задачи на единицу (K → K−1),
 «откусывая» последнюю размерность:

 • n(nK, nK−1, …, n1)   = n(nK, nK−1, …, n2, 0) + n1

 • n(nK, nK−1, …, n2, 0)   = n(nK, nK−1, …, n2)⋅N1

•В   итоге:

 • n(nK, nK-1, …, n1)   = (((…(nK⋅NK−1+nK−1)…))⋅N2+n2)⋅N1+n1
FORTRAN-STYLE


• «Откусываем»    первую размерность:

 • n(nK, nK−1, …, n1)   = n(0, nK−1, …, n1) + nK

 • n(0, nK−1, …, n1)   = n(nK−1, …, n1)⋅NK
ДВА СПОСОБА СМОТРЕТЬ
      НА ДАННЫЕ




 «Белый ящик»     «Черный ящик»
   (прозрачный)     (непрозрачный)


  Устройство        Операции
ОПЕРАЦИИ НАД ДАННЫМИ
•   Записи:                           •   Массив:

    •   Прочитать элемент по имени.       •   Прочитать элемент по
                                              индексу.
    •   Изменить элемент по имени.
                                          •   Изменить элемент по индексу.
    •   Добавить новый элемент.
                                          •   Изменить размер массива.
    •   Удалить элемент.
                                          •   Добавить элемент.

                                          •   Удалить элемент.
«ПРОДВИНУТОСТЬ»
          СТРУКТУР ДАННЫХ

• Количество«степеней свободы» (возможных операций со
 структурой данных).

• Рост   количества степеней свободы возможен:

 • за   счет усложнения внутренней структуры;

 • за   счет понижения быстродействия.
СТЕК

•   Абстрактный тип данных.

•   Базовые операции:

    •   Вставка элемента (push).

    •   Извлечение элемента
        (pop).
                                      push   pop
•   Принцип LIFO (last-in, first-
    out) – «последним вошел,
    первым вышел».
ПРИМЕНЕНИЯ СТЕКА

• Машинный     стек.

• Вычисление    выражений в обратной польской записи:

 • (1+2*4+3)     →124*+3+

 • Язык    Postscript.

• Поиск    пути в лабиринте.

• Задачи   с иерархией элементов (обход дерева).
ОЧЕРЕДЬ

•   Абстрактный тип данных.

•   Базовые операции:

    •   Вставка элемента (enqueue).

    •   Извлечение элемента
        (dequeue).                    enqueue

•   Принцип FIFO (first-in, first-
    out) – «первым вошел, первым
    вышел».                                     dequeue
ПРИМЕНЕНИЕ ОЧЕРЕДЕЙ

• Обработка   отложенных запросов.

 Порождение
  запросов

                    оооооооооооооооочередь




                                             Обработка
                                              запросов
РЕАЛИЗАЦИЯ СТЕКА

• Статический   массив достаточно большого размера.

                      int stack[99999];
                      int sp = 0;

                      stack[sp] = 10;
                      sp++;

                      stack[sp] = 20;
                      sp++;

                      sp--;
                      stack[sp]; // => 20
СВЯЗНЫЕ СПИСКИ


• Связныйсписок (linked list) – линейно упорядоченный
 набор элементов, каждый из которых содержит связь со
 следующим элементом.


       Голова


                                Хвост
ОПЕРАЦИИ СО СВЯЗНЫМ
       СПИСКОМ

• Вставка   элемента в голову.

• Вставка   в середину.

• Удаление    элемента.

• Обход     списка.

• Поиск   элемента по критерию.
СВОЙСТВА СВЯЗНОГО
           СПИСКА


• Динамическая    структура данных.

• Вставка   и удаление выполняются за O(1).

• Медленный    поиск по номеру (индексирование): O(n).
ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
       СПИСКОВ


• Многочлены    (символьная алгебра).

• Реализация   стеков и очередей.

• Цепочки   кластеров в файловых системах.
РЕАЛИЗАЦИЯ СТЕКА
• Связный  список с использованием динамической памяти
 (malloc и free).
   struct StackNode {            struct StackNode *root, *n1, *n2;
       int n;
       struct StackNode *next;   n1 = (struct StackNode *)malloc(
   };                                    sizeof(struct StackNode));
                                 n1->n = 10;
                                 n1->next = 0;
                                 root = n1;

                                 n2 = (struct StackNode *)malloc(
                                         sizeof(struct StackNode));
                                 n2->n = 20;
                                 n2->next = root;
                                 root = n2;

                                 root->n; // => 20
                                 root = root->next;
ДВУСВЯЗНЫЙ СПИСОК


  Голова


                           Хвост


 Преимущество: одинаковая легкость
      операций в обе стороны
КОЛЬЦЕВОЙ СВЯЗНЫЙ
     СПИСОК


   Голова?
ПРИМЕНЕНИЕ КОЛЬЦЕВЫХ
       СПИСКОВ


• Список   вершин многоугольника.

• Список   процессов в системе с разделением времени.

• Кольцо   буферов ввода/вывода.
ДВУСВЯЗНЫЙ КОЛЬЦЕВОЙ
       СПИСОК
Конец




КОНЕЦ ПЯТОЙ ЛЕКЦИИ
     Чем больше степеней свободы, тем лучше.
Если не приходится за это слишком дорого платить.

ОПК № 5 – Составные типы данных, списки

  • 1.
    ОСНОВЫ ПРОГРАММНОГО КОНСТРУИРОВАНИЯ Лекция № 5 19 марта 2013 г.
  • 2.
  • 3.
    ЗАПИСИ • Объединяют разнотипные данные, относящиеся к одному объекту из предметной области. struct Point { struct Order { double x, y, z; struct User *user; }; struct Date date; int nitems; struct Planet { struct OrderItem *items; const char *name; }; double mass; double radius; /* .... */ };
  • 4.
    МАССИВЫ • Множество однотипных данных: • Набор временных отсчетов. • Векторы и матрицы. • Набор строк. • Элементы массива хранятся в смежных ячейках памяти.
  • 5.
    ОДНОМЕРНЫЙ МАССИВ • A0 – адрес начала массива. •s – размер элемента массива. • Чему равен A(n) – адрес n-го элемента массива? int a[5]; Индекс 0 1 2 3 4 Адрес A0 ? ? ? ?
  • 6.
  • 7.
    ДВУМЕРНЫЙ МАССИВ int a[2][3]; С-style или FORTRAN-style k k 0 1 2 0 2 4 m m 3 4 5 1 3 5 n = 3m+k a[m][k] n = 2k+m
  • 8.
    N-МЕРНЫЙ МАССИВ •K размерностей: A[NK][NK-1]....[N1]. • А(nK, nK-1, …, n1) = A0 + s⋅n(nK, nK-1, …, n1). • n(nK, nK-1, …, n1) =?
  • 9.
    C-STYLE • Уменьшаем порядокзадачи на единицу (K → K−1), «откусывая» последнюю размерность: • n(nK, nK−1, …, n1) = n(nK, nK−1, …, n2, 0) + n1 • n(nK, nK−1, …, n2, 0) = n(nK, nK−1, …, n2)⋅N1 •В итоге: • n(nK, nK-1, …, n1) = (((…(nK⋅NK−1+nK−1)…))⋅N2+n2)⋅N1+n1
  • 10.
    FORTRAN-STYLE • «Откусываем» первую размерность: • n(nK, nK−1, …, n1) = n(0, nK−1, …, n1) + nK • n(0, nK−1, …, n1) = n(nK−1, …, n1)⋅NK
  • 11.
    ДВА СПОСОБА СМОТРЕТЬ НА ДАННЫЕ «Белый ящик» «Черный ящик» (прозрачный) (непрозрачный) Устройство Операции
  • 12.
    ОПЕРАЦИИ НАД ДАННЫМИ • Записи: • Массив: • Прочитать элемент по имени. • Прочитать элемент по индексу. • Изменить элемент по имени. • Изменить элемент по индексу. • Добавить новый элемент. • Изменить размер массива. • Удалить элемент. • Добавить элемент. • Удалить элемент.
  • 13.
    «ПРОДВИНУТОСТЬ» СТРУКТУР ДАННЫХ • Количество«степеней свободы» (возможных операций со структурой данных). • Рост количества степеней свободы возможен: • за счет усложнения внутренней структуры; • за счет понижения быстродействия.
  • 14.
    СТЕК • Абстрактный тип данных. • Базовые операции: • Вставка элемента (push). • Извлечение элемента (pop). push pop • Принцип LIFO (last-in, first- out) – «последним вошел, первым вышел».
  • 15.
    ПРИМЕНЕНИЯ СТЕКА • Машинный стек. • Вычисление выражений в обратной польской записи: • (1+2*4+3) →124*+3+ • Язык Postscript. • Поиск пути в лабиринте. • Задачи с иерархией элементов (обход дерева).
  • 16.
    ОЧЕРЕДЬ • Абстрактный тип данных. • Базовые операции: • Вставка элемента (enqueue). • Извлечение элемента (dequeue). enqueue • Принцип FIFO (first-in, first- out) – «первым вошел, первым вышел». dequeue
  • 17.
    ПРИМЕНЕНИЕ ОЧЕРЕДЕЙ • Обработка отложенных запросов. Порождение запросов оооооооооооооооочередь Обработка запросов
  • 18.
    РЕАЛИЗАЦИЯ СТЕКА • Статический массив достаточно большого размера. int stack[99999]; int sp = 0; stack[sp] = 10; sp++; stack[sp] = 20; sp++; sp--; stack[sp]; // => 20
  • 19.
    СВЯЗНЫЕ СПИСКИ • Связныйсписок(linked list) – линейно упорядоченный набор элементов, каждый из которых содержит связь со следующим элементом. Голова Хвост
  • 20.
    ОПЕРАЦИИ СО СВЯЗНЫМ СПИСКОМ • Вставка элемента в голову. • Вставка в середину. • Удаление элемента. • Обход списка. • Поиск элемента по критерию.
  • 21.
    СВОЙСТВА СВЯЗНОГО СПИСКА • Динамическая структура данных. • Вставка и удаление выполняются за O(1). • Медленный поиск по номеру (индексирование): O(n).
  • 22.
    ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ СПИСКОВ • Многочлены (символьная алгебра). • Реализация стеков и очередей. • Цепочки кластеров в файловых системах.
  • 23.
    РЕАЛИЗАЦИЯ СТЕКА • Связный список с использованием динамической памяти (malloc и free). struct StackNode { struct StackNode *root, *n1, *n2; int n; struct StackNode *next; n1 = (struct StackNode *)malloc( }; sizeof(struct StackNode)); n1->n = 10; n1->next = 0; root = n1; n2 = (struct StackNode *)malloc( sizeof(struct StackNode)); n2->n = 20; n2->next = root; root = n2; root->n; // => 20 root = root->next;
  • 24.
    ДВУСВЯЗНЫЙ СПИСОК Голова Хвост Преимущество: одинаковая легкость операций в обе стороны
  • 25.
    КОЛЬЦЕВОЙ СВЯЗНЫЙ СПИСОК Голова?
  • 26.
    ПРИМЕНЕНИЕ КОЛЬЦЕВЫХ СПИСКОВ • Список вершин многоугольника. • Список процессов в системе с разделением времени. • Кольцо буферов ввода/вывода.
  • 27.
  • 28.
    Конец КОНЕЦ ПЯТОЙ ЛЕКЦИИ Чем больше степеней свободы, тем лучше. Если не приходится за это слишком дорого платить.