Скачать презентацию лекция 9 СПИСКИ ОКОНЧАНИЕ ГРАФЫ План лекции Скачать презентацию лекция 9 СПИСКИ ОКОНЧАНИЕ ГРАФЫ План лекции

09 Списки (окончание) Графы.pptx

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

лекция 9 СПИСКИ (ОКОНЧАНИЕ). ГРАФЫ лекция 9 СПИСКИ (ОКОНЧАНИЕ). ГРАФЫ

План лекции Очередь Реализация с помощью списка Реализация с помощью циклического буфера Графы Определения План лекции Очередь Реализация с помощью списка Реализация с помощью циклического буфера Графы Определения Вычисление кратчайших расстояний с помощью очереди

Очередью называется линейный список, в котором все включения производятся на одном конце списка, все Очередью называется линейный список, в котором все включения производятся на одном конце списка, все исключения – на другом его конце FIFO (first-in-first-out) – первый вошел, первый вышел Исключить Начало Включить Второй Третий Четвертый Конец

Операции работы с очередью create(&Q) – создает очередь makeempty (&Q) – делает очередь Q Операции работы с очередью create(&Q) – создает очередь makeempty (&Q) – делает очередь Q пустой front (&Q) – выдает значение первого элемента очереди, не удаляя его get(&Q) – выдает значение первого элемента очереди и удаляет его из очереди put(&Q, x) – помещает в конец очереди Q новый элемент со значением x empty (&Q) -- если очередь пуста, то 1 (истина), иначе 0 (ложь) destroy(&Q) -- уничтожает очередь

Реализация очереди с помощью списка struct Element { T struct Element * }; value; Реализация очереди с помощью списка struct Element { T struct Element * }; value; next; struct Queue { struct Element * }; front; back; typedef struct Queue typedef Element * Queue; ptr. Element;

Create, put void create(Queue *q) { q->front = q->back = NULL; } void put(Queue Create, put void create(Queue *q) { q->front = q->back = NULL; } void put(Queue *q, T a) { ptr. Element p = malloc(sizeof(*p)); p->value = a; p->next = NULL; if (q->front == NULL) q->front = p; else q->back->next = p; q->back = p; }

Get, empty T get(Queue *q) { ptr. Element p = q->front; T a = Get, empty T get(Queue *q) { ptr. Element p = q->front; T a = p->value; q->front = p->next; free(p); if (q->front == NULL) q->back = NULL; return a; } int empty(const Queue *q) { return q->front == NULL; }

Реализация очереди с помощью циклического буфера value[ 6 0] [5] va lue va [3] Реализация очереди с помощью циклического буфера value[ 6 0] [5] va lue va [3] Queue; ptr. Element; lue [4] e valu front 1] [ alue v ] va typedef struct Queue typedef T * val ue[ 7] ue[ val struct Queue { T *value; int front; int back; int size; }; back [2]

Create, put void create(Queue *q, int size) { q->value = malloc(*q->value*size); q->front = q->back Create, put void create(Queue *q, int size) { q->value = malloc(*q->value*size); q->front = q->back = 0; q->size = size; } void put(Queue *q, T a) { q->value[q->back] = a; // Как узнать, что в очереди нет места? q->back = (q->back+1) % q->size; }

Get, empty T get(Queue *q) { T a = q->value[q->front]; q->front = (q->front+1) % Get, empty T get(Queue *q) { T a = q->value[q->front]; q->front = (q->front+1) % q->size; return a; } int empty(const Queue *q) { return q->front == q->back; }

Пример работы с очередью int main() { Queue Q; create(&Q); // create(&Q, 100); put(&Q, Пример работы с очередью int main() { Queue Q; create(&Q); // create(&Q, 100); put(&Q, 5); put(&Q, 7); while (!empty(Q)) { int b = get(Q); printf("%dn", b); } destroy(&Q); return 0; }

Дек (double-ended queue) очередь с двумя концами Деком называется линейный список, в котором включения Дек (double-ended queue) очередь с двумя концами Деком называется линейный список, в котором включения и исключения производятся на обоих концах списка Включить или исключить Левый конец Включить или исключить Второй слева Третий слева или справа Второй справа Правый конец

Графы Очередь Реализация с помощью списка Реализация с помощью циклического буфера Графы Определения Вычисление Графы Очередь Реализация с помощью списка Реализация с помощью циклического буфера Графы Определения Вычисление кратчайших расстояний с помощью очереди

Упорядоченная пара Пусть А и В – множества Упорядоченная пара (а, b), состоящая из Упорядоченная пара Пусть А и В – множества Упорядоченная пара (а, b), состоящая из а А и b B, это конечное множество {a, b}} Упорядоченные пары (а, b) и (с, d) равны, если а = с и b = d Почему? Чем отличается упорядоченная пара от множества {а, b}?

Декартово произведение Декартовым произведением Ах. В множеств A и B называется множество упорядоченных пар Декартово произведение Декартовым произведением Ах. В множеств A и B называется множество упорядоченных пар { (а, b) | а А и b B } Пример A = {1, 2} В = {2, 3, 4} Aх. B = {(1, 2), (1, 3), (1, 4), (2, 2), (2, 3), (2, 4)}

Отношения Пусть А и В —множества Отношением из А в В называется любое подмножество Отношения Пусть А и В —множества Отношением из А в В называется любое подмножество множества Ах. В A называется областью определения отношения R В называется множеством значений отношения R Факт (а, b) R сокращенно записывается а. Rb Отношение {(b, а) | (а, b) R} называется обратным к отношению R и часто обозначается через R-1. Ax. B B R A

Виды отношений Пусть A—множество Отношение R называется на А рефлексивным, если а. Rа для Виды отношений Пусть A—множество Отношение R называется на А рефлексивным, если а. Rа для всех a из А симметричным, если а. Rb влечет b. Ra для a и b из A транзитивным, если для любых а, b и с из A из а. Rb и b. Rс следует а. Rс Рефлексивное, симметричное и транзитивное отношение называется отношением эквивалентности Отношение эквивалентности на множестве A разбивает множество A на непересекающиеся подмножества, называемые классами эквивалентности Приведите примеры каждого вида отношений

Графы Графом называется пара (А, R), где А — конечное множество, а R — Графы Графом называется пара (А, R), где А — конечное множество, а R — отношение на множестве А Элементы А называются вершинами (узлами) Элементы R называются дугами (ребрами) Если отношение R несимметричное, то граф ориентированный Если отношение R симметричное, то граф неориентированный

Изображение графов на плоскости Вершины графа изображают точками Дуги графа изображают прямо- или криволинейных Изображение графов на плоскости Вершины графа изображают точками Дуги графа изображают прямо- или криволинейных отрезков Пример изображения графа на плоскости A={1, 2, 3, 4} , R = {(1, 1), (1, 2), (2, 3), (2, 4), (3, 4), (4, 1), (4, 3)} 2 1 3 4

Изображение графов на плоскости Изображения дуг графа могут пересекаться -- точки пересечения не являются Изображение графов на плоскости Изображения дуг графа могут пересекаться -- точки пересечения не являются вершинами Граф, который можно изобразить на плоскости без пересечений дуг, называется планарным. Пример различных изображений графа на плоскости A={1, 2, 3, 4} , R = {(1, 2), (1, 3), (2, 4), (3, 4), (4, 1)} 2 1 3 4

Дуги графа Пара (а, b) R называется дугой (ребром) графа G Дуга выходит из Дуги графа Пара (а, b) R называется дугой (ребром) графа G Дуга выходит из вершины а и входит в вершину b Вершина а предшествует вершине b, а вершина b следует за вершиной a Вершина b смежна с вершиной a a b

Путь и цикл в графе Последовательность вершин (а 0, а 1, . . . Путь и цикл в графе Последовательность вершин (а 0, а 1, . . . , аn), n≥ 1, называется путем (маршрутом) длины n из вершины а 0 в вершину аn, если для каждого 1≤i≤n существует дуга, выходящая из вершины аi-1 и входящая в вершину аi Если существует путь из вершины а 0 в вершину аn, то говорят, что аn достижима из а 0 Циклом называется путь (а 0, а 1, . . . , аn), т. ч. а 0 = аn

Путь и цикл в графе A={1, 2, 3, 4} R = {(1, 1), (1, Путь и цикл в графе A={1, 2, 3, 4} R = {(1, 1), (1, 2), (2, 3), (2, 4), (3, 4), (4, 1), (4, 3)} Путь ( 1, 2, 4, 3 ) Цикл ( 1, 2, 3, 4, 1 ) 2 1 3 4

Степень вершины Степенью по входу (полустепенью входа) вершины называется число входящих в нее дуг Степень вершины Степенью по входу (полустепенью входа) вершины называется число входящих в нее дуг Степенью по выходу (полустепенью исхода) вершины называется число выходящих из нее дуг Если граф неориентированный, то степенью вершины называется количество инцидентных с ней ребер 2 1 3 4 Для вершины 2: полустепень входа = 1 полустепень исхода = 2

Ациклические графы Ациклическим графом называется (ориентированный) граф, не имеющий циклов Вершина, степень по входу Ациклические графы Ациклическим графом называется (ориентированный) граф, не имеющий циклов Вершина, степень по входу которой равна 0, называется базовой Вершина, степень по выходу которой равна 0, называется листом (концевой вершиной) 5 8 3 2 1 6 9 4 7

Дуга и путь в ациклическом графе Пусть (a, b) – дуга в ациклическом графе Дуга и путь в ациклическом графе Пусть (a, b) – дуга в ациклическом графе Вершина a называется прямым предком b, b называется прямым потомком a Если существует путь из a в b, то a называется предком b, b называется потомком a a b

Матрица смежностей Пусть дан граф G = (V, E), N = |V|, M = Матрица смежностей Пусть дан граф G = (V, E), N = |V|, M = |E| Матрица смежностей для графа G – это матрица A размера Nх. N, состоящая из 0 и 1, в которой A[i, j]=1 тогда и только тогда, когда есть ребро из узла i в узел j 1 2 3 4 1 0 0 2 0 0 1 1 3 0 0 0 1 4 1 0 2 1 3 4

Матрица инцидентностей для графа G – это матрица B размера Nх. M, в которой Матрица инцидентностей для графа G – это матрица B размера Nх. M, в которой 1, если ребро j выходит из вершины i B[i, j]= -1, если ребро j входит в вершину i 0, если ребро j не связано с вершиной i 2 1 6 3 1 1 2 5 4 3 4 1 2 3 4 5 6 0 1 -1 0 0 0 1 0 1 -1

Списки смежностей Списком смежностей для узла v называется список всех узлов w, смежных с Списки смежностей Списком смежностей для узла v называется список всех узлов w, смежных с v 1 2 4 2 NULL 3 1 2 3 5 NULL 3 4 5 NULL 4 NULL 5 1 3 5 4 4 NULL

Табличное представление списков смежностей 2 1 3 5 4 1 2 3 4 5 Табличное представление списков смежностей 2 1 3 5 4 1 2 3 4 5 6 7 8 9 10 11 12 13 Номер вершины Следующий 1 6 2 8 3 10 4 0 5 12 2 7 4 0 3 9 5 0 4 11 5 0 1 13 3 14

Метод поиска в ширину Один из способов нумерации вершин произвольного графа Проектирование ИС и Метод поиска в ширину Один из способов нумерации вершин произвольного графа Проектирование ИС и печатных плат, . . . Основа большого числа алгоритмов Поиск кратчайших путей Вычисление максимального потока в графе Проверка связности Breadth-first search, BFS

Метод поиска в ширину Пусть дан граф G и выбрана некоторая его вершина s Метод поиска в ширину Пусть дан граф G и выбрана некоторая его вершина s Поиск в ширину вычисляет для каждой вершины u два номера П[u] предшественика вершины u при поиске в ширину d[u] кратчайшее расстояние от s до u Схема алгоритма Шаг 1: d[s] = 0 Шаг n: обрабатываем все вершины на расстоянии n-1 от s Каждого соседа v вершины u с пометкой d[u] = n-1 нумеруем П[v] = u и d[v] = n

Метод поиска в ширину 2 10 3 6 1 5 4 8 9 7 Метод поиска в ширину 2 10 3 6 1 5 4 8 9 7

Метод поиска в ширину d[2] = 1 2 10 3 1 5 4 8 Метод поиска в ширину d[2] = 1 2 10 3 1 5 4 8 9 d[3] = 1 6 d[6] = 1 7

Метод поиска в ширину d[2] = 1 d[1] = 2 2 1 4 8 Метод поиска в ширину d[2] = 1 d[1] = 2 2 1 4 8 9 d[5] = 2 10 3 d[3] = 1 6 d[6] = 1 5 d[8] = 2 7 d[7] = 2

Метод поиска в ширину d[2] = 1 d[1] = 2 d[4] = 3 1 Метод поиска в ширину d[2] = 1 d[1] = 2 d[4] = 3 1 4 8 9 d[8] = 2 d[9] = 3 2 d[5] = 2 10 3 d[3] = 1 6 d[6] = 1 5 7 d[7] = 2

Метод поиска в ширину d[2] = 1 d[1] = 2 d[4] = 3 1 Метод поиска в ширину d[2] = 1 d[1] = 2 d[4] = 3 1 4 V Расстояние до 10 Путь через 1 2 2 2 1 3 1 4 3 2, 1 7 5 2 2 или 6 d[7] = 2 6 1 3 7 2 6 8 2 2 9 3 2, 8 2 d[5] = 2 10 3 d[3] = 1 6 d[6] = 1 5 8 9 d[8] = 2 d[9] = 3

Алгоритм BFS (матрица смежности граф G, число вершин n, вершина s) { for (u Алгоритм BFS (матрица смежности граф G, число вершин n, вершина s) { for (u = 0; u < n; u++) d[u] = n; // почему? } d[s] = 0; put(s, Q); while (! empty(Q)) { u = get(Q); for (v = 0; v < n; v++) if (G[v][u] == 1) { // для всех соседей u if (d[v] > d[u]+1) { d[v]= d[u]+1; put(Q, v); }} }

Заключение Очередь Реализация с помощью списка Реализация с помощью циклического буфера Графы Определения Вычисление Заключение Очередь Реализация с помощью списка Реализация с помощью циклического буфера Графы Определения Вычисление кратчайших расстояний с помощью очереди

КОНЕЦ ЛЕКЦИИ КОНЕЦ ЛЕКЦИИ

Односвязный граф Граф называется сильно связным, если для любых двух разных вершин а и Односвязный граф Граф называется сильно связным, если для любых двух разных вершин а и b существует путь из a в b. Содержит одну компоненту связности - Существует путь из любой вершины в любую другую вершину - Существует путь из заданной вершины в любую другую вершину - Содержит связный подграф, включающий все вершины исходного графа - Содержит в качестве подграфа дерево, включающее все вершины исходного графа (такое дерево называется остовным) - При произвольном делении его вершин на 2 группы всегда существует хотя бы 1 ребро, соединяющее пару вершин из разных групп. Компонента связности графа — некоторое множество вершин графа такое, что для любых двух вершин из этого множества существует путь из одной в другую, и не существует пути из вершины этого множества в вершину не из этого множества.

Линейный список - это множество, состоящее из n (n≥ 0) узлов (элементов) X[1], X[2], Линейный список - это множество, состоящее из n (n≥ 0) узлов (элементов) X[1], X[2], … , X[n], структурные свойства которого ограничены линейным (одномерным) относительным положением узлов (элементов), т. е. следующими условиями: если n > 0, то X[1] – первый узел; если 1 < k < n, то k-му узлу X[k] предшествует узел X[k-1], а за узлом X[k] следует узел X[k+1]; X[n] – последний узел.

Реализация двусвязного списка struct Tlist 2 { char word[256]; //область данных struct Tlist 2 Реализация двусвязного списка struct Tlist 2 { char word[256]; //область данных struct Tlist 2 *next; //ссылка на следующий узел struct Tlist 2 *prev; //ссылка на предыдущий узел }; struct Tlist 2 * Head = NULL; //голова списка struct Tlist 2* new_el_2(char new. Word[]) { struct Tlist 2 * p=(struct Tlist 2 *) malloc( sizeof(struct Tlist 2)); if(p){ strcpy(p->word, new. Word); //записать слово p->next = NULL; //следующего узла нет p->prev = NULL; //предыдущего узла нет } return p; //результат функции – адрес элемента }

Списки смежных вершин в графе 1 2 4 2 1 2 3 3 5 Списки смежных вершин в графе 1 2 4 2 1 2 3 3 5 4 3 5 5 4 4 NULL 5 1 3 4

Реализация списка смежностей struct Ie_list{ struct Ie_list *next; struct Tlist *simple. List; }; struct Реализация списка смежностей struct Ie_list{ struct Ie_list *next; struct Tlist *simple. List; }; struct Ie_list *list; list=(struct Ie_list*)malloc(sizeof(struct Ie_list)); If (list) { list->next=NULL; list->simple. List = new_el(“hello!”); }

Реализация односвязного списка struct data_and_link { char data[256]; struct data_and_link *link; }; // данные Реализация односвязного списка struct data_and_link { char data[256]; struct data_and_link *link; }; // данные // связь // список данных typedef struct data_and_link *list; list add_data(const char d[], list L) { list new_L = (list) malloc(sizeof(*new_L)); if (new_L != NULL) { // успешно? strcpy(new_L->data, d); // новые данные new_L->link = L; // привязаны старым } return new_L; // результат – обновлённый список }

Пример работы с односвязным списком struct Tlist *head=NULL; struct Tlist *p; int main() { Пример работы с односвязным списком struct Tlist *head=NULL; struct Tlist *p; int main() { list L = add_data("A", add_data("B", add_data("C", NULL))); } p = (struct Tlist*) malloc(sizeof(struct Tlist)); p->data = 5; p->next = NULL; head = p; head p 5 NULL

Вставка элемента в односвязный список после элемента с адресом prev typedef struct Tlist *Node; Вставка элемента в односвязный список после элемента с адресом prev typedef struct Tlist *Node; //указатель на элемент void Add. After (Node prev, char data[]) { Node cur = new_el(data); if (cur) { cur ->next = prev->next; prev->next = cur; } }

Реализация стека strict Tlist { int data; struct Tlist *next; } typedef struct Tlist Реализация стека strict Tlist { int data; struct Tlist *next; } typedef struct Tlist * Stack 1; // в этом случае работа // такая же, как с односвязным списком typedef struct stack {struct Tlist * top; } Stack; typedef struct stack {Stack 1 top; } Stack; Опустошение стека void makenull (Stack *S){ struct Tlist *p; while (S->top) { p = S->top; S->top = p->next; free(p); } }

Создание стека Stack * create () { Stack *S; S = (Stack *)malloc(sizeof(Stack)); S->top Создание стека Stack * create () { Stack *S; S = (Stack *)malloc(sizeof(Stack)); S->top = NULL; return S; } Верхушка стека int top (Stack *S) { if (S->top) return (S->top->data); else return 0; //здесь может быть реакция на //ошибку – обращение к пустому стеку }

Взятие верхнего элемента стека int pop(Stack *S){ int a; struct Tlist *p; p = Взятие верхнего элемента стека int pop(Stack *S){ int a; struct Tlist *p; p = S->top; a = p->data; S-> top = p->next; free(p); return a; }

Помещение в стек нового элемента void push(int a, Stack *S){//return NULL? struct Tlist *p; Помещение в стек нового элемента void push(int a, Stack *S){//return NULL? struct Tlist *p; p =(struct Tlist *)malloc(sizeof(struct Tlist)); if(p) { p->data = a; p->next = S-> top; S->top = p ; } } Проверка на пустоту int empty (Stack *S) { return (S->top == NULL); }