Скачать презентацию Узлы списки стеки и очереди 2 Динамические Скачать презентацию Узлы списки стеки и очереди 2 Динамические

стеки_очереди.ppt

  • Количество слайдов: 32

Узлы, списки, стеки и очереди Узлы, списки, стеки и очереди

2 Динамические структуры данных Строение: набор узлов, объединенных с помощью ссылок. Как устроен узел: 2 Динамические структуры данных Строение: набор узлов, объединенных с помощью ссылок. Как устроен узел: ссылки на другие узлы данные Типы структур: списки односвязный NULL двунаправленный (двусвязный) NULL циклические списки (кольца)

3 Списки: новые типы данных Что такое список: 1) пустая структура – это список; 3 Списки: новые типы данных Что такое список: 1) пустая структура – это список; 2) список – это начальный узел (голова) и связанный с ним список. NULL Структура узла: struct Node { char word[40]; int count; Node *next; }; PNode Head = NULL; Указатель на эту структуру: typedef Node *PNode; Адрес начала списка:

4 Операции производимые над списками: 1. Создание нового узла. 2. Добавление узла: a) в 4 Операции производимые над списками: 1. Создание нового узла. 2. Добавление узла: a) в начало списка; b) в конец списка; c) в заданную позицию списка; 3. Поиск нужного узла в списке. 4. Удаление узла.

5 Создание узла Функция Create. Node (создание узла): PNode Create. Node ( char New. 5 Создание узла Функция Create. Node (создание узла): PNode Create. Node ( char New. Word[] ) { PNode New. Node = new Node; strcpy(New. Node->word, New. Word); New. Node->count = 1; New. Node->next = NULL; return New. Node; }

6 Добавление узла в начало списка 1) Установить ссылку нового узла на 1 элемент 6 Добавление узла в начало списка 1) Установить ссылку нового узла на 1 элемент списка: New. Node NULL New. Node->next = Head NULL 2) Установить новый узел как 1 элемент списка: New. Node Head = New. Node; Head NULL void Add. First (PNode & Head, PNode New. Node) { New. Node->next = Head; Head = New. Node; }

7 Добавление узла в заданную позицию 1) Установить ссылку нового узла на узел, следующий 7 Добавление узла в заданную позицию 1) Установить ссылку нового узла на узел, следующий за p: 2) Установить ссылку узла p на новый узел: void Add. After (PNode p, PNode New. Node) { New. Node->next = p->next; p->next = New. Node; }

8 Проход по списку Задача: выполнение действий над каждым элементом списка. Алгоритм: 1) устанавливаем 8 Проход по списку Задача: выполнение действий над каждым элементом списка. Алгоритм: 1) устанавливаем указатель q на 1 элемент списка; 2) если указатель q принимает значение NULL (конец списка), то прекращаем выполнение действий; 3) выполняем заданные действия над узлом с адресом q ; 4) переходим к следующему узлу, q->next. . PNode q = Head; while ( q != NULL ) {. . . q = q->next; }. . .

9 Добавление узла в конец списка Алгоритм: 1) находим последний узел q, такой что 9 Добавление узла в конец списка Алгоритм: 1) находим последний узел q, такой что выполняется условие q>next равен NULL; 2) добавляем узел после узла с адресом q (процедура Add. After). Особый случай: добавление в пустой список. void Add. Last ( PNode &Head, PNode New. Node ) { PNode q = Head; if ( Head == NULL ) { Add. First( Head, New. Node ); return; } while ( q->next ) q = q->next; Add. After ( q, New. Node ); }

10 Добавление узла перед заданным void Add. Before ( PNode & Head, PNode p, 10 Добавление узла перед заданным void Add. Before ( PNode & Head, PNode p, PNode New. Node ) { PNode q = Head; if ( Head == p ) { Add. First ( Head, New. Node ); return; } while ( q && q->next != p ) q = q->next; if ( q ) Add. After(q, New. Node); }

11 Добавление добавление узла в заданную позицию Алгоритм: 1) поменять местами данные нового узла 11 Добавление добавление узла в заданную позицию Алгоритм: 1) поменять местами данные нового узла и узла p; 2) установить ссылку узла p на New. Node. void Add. Before 2 ( PNode p, PNode New. Node ) { Node temp; temp = *p; *p = *New. Node; *New. Node = temp; p->next = New. Node; }

12 Пример поиска слова в списке PNode Find ( PNode Head, char New. Word[] 12 Пример поиска слова в списке PNode Find ( PNode Head, char New. Word[] ) { PNode q = Head; while (q && strcmp(q->word, New. Word)) q = q->next; return q; }

13 Удаление узла void Delete. Node ( PNode &Head, PNode p) { PNode q 13 Удаление узла void Delete. Node ( PNode &Head, PNode p) { PNode q = Head; if ( Head == p ) Head = p->next; else { while ( q && q->next != p ) q = q->next; if ( q == NULL ) return; q->next = p->next; } delete p; }

14 Двусвязные списки Структура узла: struct Node { char word[40]; int count; Node *next; 14 Двусвязные списки Структура узла: struct Node { char word[40]; int count; Node *next; Node *prev; }; Указатель на эту структуру: typedef Node *PNode; Адреса «головы» и «хвоста» : PNode Head = NULL; PNode Tail = NULL;

15 Стек – это линейная структура данных, в которой добавление и удаление элементов возможно 15 Стек – это линейная структура данных, в которой добавление и удаление элементов возможно только с одного конца (вершины стека). Stack = кипа, куча, стопка (англ. ) LIFO = Last In – First Out «Кто последним вошел, тот первым вышел» . Операции со стеком: 1) добавить элемент на вершину (Push = втолкнуть); 2) снять элемент с вершины (Pop = вылететь со звуком).

16 Пример работы со стеком [ ( ( [ ( [ [ { { 16 Пример работы со стеком [ ( ( [ ( [ [ { { Алгоритм: 1) в начале стек пуст; 2) в цикле просматриваем все символы строки по порядку; 3) если очередной символ – открывающая скобка, заносим ее на вершину стека; 4) если символ – закрывающая скобка, проверяем вершину стека: там должна быть соответствующая открывающая скобка (если это не так, то ошибка); 5) если в конце стек не пуст, выражение неправильное.

17 Реализация стека (массив) Структура-стек: const MAXSIZE = 100; struct Stack { char data[MAXSIZE]; 17 Реализация стека (массив) Структура-стек: const MAXSIZE = 100; struct Stack { char data[MAXSIZE]; // стек на 100 символов int size; // число элементов }; Добавление элемента: int Push ( Stack &S, char x ) { if ( S. size == MAXSIZE ) return 0; S. data[S. size] = x; S. size ++; return 1; }

18 Реализация стека (массив) Снятие элемента с вершины: char Pop ( Stack &S ) 18 Реализация стека (массив) Снятие элемента с вершины: char Pop ( Stack &S ) { if ( S. size == 0 ) return char(255); S. size --; return S. data[S. size]; } Проверка пустой или нет? int is. Empty ( Stack &S ) { if ( S. size == 0 ) return 1; else return 0; }

19 Пример программы void main() { char br 1[3] = { '(', '[', '{' 19 Пример программы void main() { char br 1[3] = { '(', '[', '{' }; char br 2[3] = { ')', ']', '}' }; char s[80], upper; int i, k, error = 0; Stack S; S. size = 0; printf("Введите выражение со скобками > "); gets ( s ); . . . // здесь будет основной цикл обработки if ( ! error && (S. size == 0) ) printf("n. Выpажение пpавильноеn"); else printf("n. Выpажение непpавильноеn");

20 Обработка строки (основной цикл) for ( i = 0; i < strlen(s); i++ 20 Обработка строки (основной цикл) for ( i = 0; i < strlen(s); i++ ) { for ( k = 0; k < 3; k++ ) { if ( s[i] == br 1[k] ) // если открывающая скобка { Push ( S, s[i] ); // втолкнуть в стек break; } if ( s[i] == br 2[k] ) // если закрывающая скобка { upper = Pop ( S ); // снять верхний элемент if ( upper != br 1[k] ) error = 1; break; } } if ( error ) break; }

21 Реализация стека (список) Структура узла: struct Node { char data; Node *next; }; 21 Реализация стека (список) Структура узла: struct Node { char data; Node *next; }; typedef Node *PNode; Добавление элемента: void Push (PNode &Head, char x) { PNode New. Node = new Node; New. Node->data = x; New. Node->next = Head; Head = New. Node;

22 Реализация стека (список) Снятие элемента с вершины: char Pop (PNode &Head) { char 22 Реализация стека (список) Снятие элемента с вершины: char Pop (PNode &Head) { char x; PNode q = Head; if ( Head == NULL ) return char(255); x = Head->data; Head = Head->next; delete q; return x; } Изменения в основной программе: Stack S; S. size = 0; . . . if ( ! error && (S. size == 0) ) printf("n. Выpажение пpавильноеn"); else printf("n. Выpажение непpавильное n");

23 Вычисление арифметических выражений Как вычислять автоматически: (a + b) / (c + d 23 Вычисление арифметических выражений Как вычислять автоматически: (a + b) / (c + d – 1) Инфиксная запись (знак операции между операндами) Префиксная запись (знак операции до операндов) / + a b - c + - 1 a + c d 1 + d Постфиксная запись (знак операции после операндов) a b + c d + - 1 / + b c + d 1 -

24 Вычисление выражений Постфиксная форма: X= ab + c d + 1 - / 24 Вычисление выражений Постфиксная форма: X= ab + c d + 1 - / d b a a 1 c a+b c c+d c+d-1 a+b a+b a+b X Алгоритм: 1) берем очередной элемент; 2) если это не знак операции, добавляем его в стек; 3) если это знак операции, то • берем из стека два операнда; • выполняем операцию и записываем результат в стек; 4) возвращаемся к шагу 1.

25 Очередь – это линейная структура данных, в которой добавление элементов возможно только с 25 Очередь – это линейная структура данных, в которой добавление элементов возможно только с одного конца (конца очереди), а удаление элементов – только с другого конца (начала очереди). FIFO = First In – First Out «Кто первым вошел, тот первым вышел» . Операции с очередью: 1) добавление элемента в конец очереди (Push. Tail = втолкнуть в конец); 2) удаление элемента с начала очереди (Pop).

26 Реализация очереди (массив) 1 1 2 2 2 3 3 1) нужно заранее 26 Реализация очереди (массив) 1 1 2 2 2 3 3 1) нужно заранее выделить массив; 2) при выборке из очереди нужно сдвигать все элементы.

27 Реализация очереди (кольцевой массив) Head Tail 1 2 2 3 3 5 4 27 Реализация очереди (кольцевой массив) Head Tail 1 2 2 3 3 5 4 3 4 2 3 2 1 3 4

28 Реализация очереди (кольцевой массив) В очереди 1 элемент: Head Tail Head == Tail 28 Реализация очереди (кольцевой массив) В очереди 1 элемент: Head Tail Head == Tail 1 Очередь пуста: Head == (Tail + 1) % N Head == Tail + 1 0 Очередь полна: Head == (Tail + 2) % N Head == Tail + 2 3 1 N-1 1 2 0 2 3 N-1

29 Реализация очереди (кольцевой массив) Структура данных: const MAXSIZE = 100; struct Queue { 29 Реализация очереди (кольцевой массив) Структура данных: const MAXSIZE = 100; struct Queue { int data[MAXSIZE]; int head, tail; }; Добавление в очередь: int Push. Tail ( Queue &Q, int x ) { if ( Q. head == (Q. tail+2) % MAXSIZE ) return 0; Q. tail = (Q. tail + 1) % MAXSIZE; Q. data[Q. tail] = x; return 1;

30 Реализация очереди (кольцевой массив) Выборка из очереди: int Pop ( Queue &Q ) 30 Реализация очереди (кольцевой массив) Выборка из очереди: int Pop ( Queue &Q ) { int temp; if ( Q. head == (Q. tail + 1) % MAXSIZE ) return 32767; temp = Q. data[Q. head]; Q. head = (Q. head + 1) % MAXSIZE; return temp; }

31 Реализация очереди (списки) Добавление элемента: void Push. Tail ( Queue &Q, int x 31 Реализация очереди (списки) Добавление элемента: void Push. Tail ( Queue &Q, int x ) { PNode New. Node; New. Node = new Node; New. Node->data = x; New. Node->next = NULL; if ( Q. Tail ) Q. Tail->next = New. Node; Q. Tail = New. Node; if ( Q. Head == NULL ) Q. Head = Q. Tail;

32 Реализация очереди (списки) Выборка элемента: int Pop ( Queue &Q ) { PNode 32 Реализация очереди (списки) Выборка элемента: int Pop ( Queue &Q ) { PNode top = Q. Head; int x; if ( top == NULL ) return 32767; x = top->data; Q. Head = top->next; if ( Q. Head == NULL ) Q. Tail = NULL; delete top; return x; }