32fba91f5941f646a08ef6970506051d.ppt
- Количество слайдов: 22
Алгоритмизация и программирование Структуры данных 10 класс по учебнику Калинина И. А. и Самылкиной Н. Н. Pro. Power. Point. Ru
Структуры данных Списки Pro. Power. Point. Ru Деревья
Основные элементы при построении Указатель • Адрес области памяти, в которой лежат данные. • Если обговорено, какие это данные, указатель может быть использован для доступа к ним. Pro. Power. Point. Ru Структурированный набор • На языке Pascal – записи (record) • Аналог массива, состоящий из переменных разного типа.
Пример структуры • Массив – индексированный набор элементарных переменных. • Массив представляет собой структуру, в которую входит один тип переменных. Pro. Power. Point. Ru
Хранение данных в структурах Статический тип • Место для всех данных отводится сразу (чаще – в начале блока), во время программы не изменяется. • Используется при объявлении переменных. Динамический тип • Количество элементов заранее неизвестно, меняется во время исполнения программы. • Память отводится и освобождается самой программой. Pro. Power. Point. Ru
Динамические структуры • • Требуют дополнительных операций! Компилятор не всегда может проконтролировать правильность выполнения! • Список — динамическая структура данных, в которой каждый элемент состоит из указателя на следующий элемент и одинакового для всех элементов набора дополнительных данных. Место элемента в последовательности определяется не номером, а указателем на него в предыдущем или в следующем по порядку элементе, т. е. частью структуры. Список хранят как вход в него, т. е. указатель на «голову» списка. Если указатель на «голову» пуст, то и список пуст. • Дерево - динамическая структура данных, которая имеет минимум два возможных выхода из каждого элемента и не имеет циклов, т. е. путей, связывающих между собою не «родственные» элементы. Pro. Power. Point. Ru
Списки Виды по количеству связей: Односвязные В структуру входит только указатель на следующий элемент. Если указатель пуст (имеет специальное значение nil), то это последний элемент. Двусвязные В структуру входят указатели на следующий и на предыдущий элементы, т. е. можно двигаться не только «вперед» , но и «назад» . Можем рассматривать не только "голову", но и "хвост". Примечание: мы будем рассматривать двусвязные списки. Pro. Power. Point. Ru
Основные операции • Указатель на «голову» списка хранится в переменной head. • Пустое значение указателя обозначим в коде как nil. 1. Добавление элемента в «голову» списка: new. List. Item = new List. Item //добавляем новый элемент new. List. Item. next = head //нынешнее первое «спускаем» new. List. Item. prev = nil //пустое значение предыдущего, т. к. его нет. if (head <> nil) // если список существовал head. prev = new. List. Item //вносим элемент первым head = new. List. Item //заносим значение как «голову» Сложность алгоритма: О(1) Алгоритм не зависит от размеров списка. Pro. Power. Point. Ru
2. Поиск элемента в списке: (т. е. элемента со значением данных target) curr. Item = head //начинаем с «головы» while ((curr. Item <> nil)and(curr. Item. data <> target)) //до тех пор, пока у нас есть список и элемент не найден curr. Item = curr. Item. next //проходим дальше, переобозначая Сложность алгоритма: О(n) В худшем случае необходимо проверить весь список. 3. Удаление элемента из списка: If (del. Item. next <> nil) //если след. элемент есть (не пуст) del. Item. next. prev = del. Item. prev //сдвигаем назад if (del. Item. prev <> nil) //если пред. элемент не пуст del. Item. prev. next = del. Item. next // «перешагиваем» на след. delete del. Item //удаляем нужный элемент При удалении элемента из списка важно сохранить его связность. Поэтому сначала мы исключаем элемент из цепочки, а потом освобождаем занятую им память. Сложность алгоритма: Если элемент не нужно искать (например, мы удаляем элемент из «головы» списка), то количество действий останется O(1), если нужно, то O(n). Pro. Power. Point. Ru
Чем полезен список? • Задание: Подумайте над вопросом, чем удобней в применении список по сравнению с массивом и когда он хуже. • Резюмируя результаты: + 1. если заранее неизвестно количество элементов; 2. не нужно заботиться о выходе за границы; 3. позволяет быстро производить вставку, удаление элементов. Pro. Power. Point. Ru 1. неудобен, когда нужен быстрый доступ к произвольному элементу (необходимо проходить каждый раз весь список или хранить указатели в отдельном массиве).
Дерево • имеют минимум два возможных выхода из каждого элемента; • не имеют циклов. Вершина - любой (каждый) в дереве; содержит указатели на потомков и некоторые данные программиста (аналогично списку). Ключ - часть данных, от которой зависит обработка дерева. Мы будем рассматривать двоичные деревья (имеющие ровно два выхода), т. е. элементом такого дерева является структура, содержащая: • указатель левой ветви, • указатель правой ветви, • некоторые полезные данные (например, некоторое число). Pro. Power. Point. Ru
Двоичные деревья Элемент N (текущий) n Элемент Q q q
Операции над деревьями • Дерево хранится как указатель на его первый элемент, который называется корневым. • Будем считать, что указатель на корень дерева хранится в переменной root. 1. Поиск элемента в дереве: cur. Item = root //начинаем с корня while ((cur. Item <> nil)and(cur. Item. data <> a)) //пока дерево не кончилось и элемент не нашёлся if (cur. Item. data > a) //рассматриваем элемент cur. Item = cur. Item. left //присваиваем меньшее значение ( «левое» ) else cur. Item = cur. Item. right //присваиваем большее или равное значение //( «правое» ) Если элемента в дереве нет, то последним текущим элементом станет nil. Сложность алгоритма: зависит от кол-ва элементов дерева и порядка, в котором их добавляли. Pro. Power. Point. Ru
2. Вставка элемента в дерево: Сложность алгоритма: если дерево сбалансировано – О(log n), если в дерево элементы добавлялись неудачно (например, по возрастанию), оно становится списком, а сложность возрастает до О(n). Дерево называется сбалансированным, если в нём мало или совсем нет узлов с одним потомком. Pro. Power. Point. Ru
Типовые структуры данных Стек (stack) Очередь Линейная структура с двумя операциями, но извлекается не последний, а первый помещенный элемент, т. е. используется принцип FIFO (First In First Out). Пример-аналогия: очередь в магазине (первый встал первый купил и вышел). Двоичное дерево поиска Pro. Power. Point. Ru Линейная структура данных, в которой есть две операции: помещения и извлечения. При извлечении всегда выдается последний помещенный в структуру элемент. Такой принцип называется LIFO ( Last In First Out, т. е. «последний зашёл – первый вышел» ). Пример-аналогия: стопка тарелок (можно брать только последнюю) или люди в набитом автобусе. В этом дереве каждый элемент имеет не более двух потомков, причем левый меньше текущего ключа, а правый больше. Могут быть реализованы и с помощью динамических, и с помощью статических структур.
Практическая часть 1. Вас просят написать программу, которая получает данные о книгах. О каждой книге будет известно название, автор, цена, количество и расположение на складе. Общее количество книг заранее неизвестно. Опишите структуру данных, которую целесообразно использовать для хранения. program task 4_18_1; Type book = record // Структура для хранения данных о конкретной книге на складе title : string; author: string; count : word; price : longword; place : word; end; p. Node = ^List. Node; // Общая структура для организации учета склада List. Node = record next : p. Node; book. Data : book; end; // Добавление элемента в список function item. List. New (title : string; author: string; count : word; price : longword; place : word; next : PNode): p. Node; begin new (Result); Result^. book. Data. title : = title; Result^. book. Data. author : = author; Result^. book. Data. count : = count; Result^. book. Data. price : = price; Result^. book. Data. place : = place; Result^. next : = next; end; // Ввод данных о книге с клавиатуры function item. List. Keyboard (next : p. Node) : p. Node; var title, author: string; Pro. Power. Point. Ru count : word; price : longword; place : word; begin write ('Введите название==>'); readln(title); write ('Введите автора==>'); readln(author); write ('Введите количество==>'); readln(count); write ('Введите цену==>'); readln(price); write ('Введите место==>'); readln(place); Result : = item. List. New (title, author, count, price, place, next); end; var head : p. Node; answ : char; begin // Создание списка repeat write('Желаете ввести новую книгу? (д/н)'); readln(answ); if answ = 'д' then head : = item. List. Keyboard(head); until answ <> 'д'; end. //Вывод списка в этой задаче не требовался. Для рассмотрения скопируйте код в компилятор!
2. Подготовьте программу, которая вводит и выводит данные о книгах. Вводиться будут данные из предыдущей задачи, а выводиться название и общая стоимость книг этого наименования. Pro. Power. Point. Ru program task 4_18_2; writeln(item^. book. Data. title, ', ', item^. book begin Type Data. price*item^. book. Data. count); book = record // Структура для храненияnew (Result); result : = item^. next; данных о конкретной книге на складе Result^. book. Data. title : = title; end; Result^. book. Data. author : = author; title : string; Result^. book. Data. count : = count; author: string; var Result^. book. Data. price : = price; count : word; head : p. Node; price : longword; Result^. book. Data. place : = place; answ : char; place : word; Result^. next : = next; begin end; // Создание списка p. Node = ^List. Node; // Общая структура repeat для организации учета склада // Ввод данных о книге с клавиатуры write('Желаете ввести новую List. Node = record function item. List. Keyboard (next : p. Node) книгу? (д/н)'); next : p. Node; readln(answ); book. Data : book; var if answ = 'д' then end; title, author: string; head : = item. List. Keyboard(head); // Функция-итератор, подробно count : word; until answ <> 'д'; рассмотренная в задачнике price : longword; iterate = function( item : p. Node): p. Node; place : word; iterator. List(head, print. List. Item); // Вывод procedure iterator. List(start : p. Node; begin всех значений списка – решение задачи iterate. Function : iterate); write ('Введите название==>'); 2 var readln(title); end. current : p. Node; write ('Введите автора==>'); begin readln(author); current : = start; write ('Введите количество==>'); repeat readln(count); current: =iterate. Function(current); write ('Введите цену==>'); readln(price); until current = nil; write ('Введите место==>'); readln(place); end; Result : = item. List. New // Добавление элемента в список (title, author, count, price, place, next); function item. List. New (title : string; end; author: string; count : word; price : longword; function print. List. Item (item : p. Node) : place : word; p. Node; next : PNode): p. Node; begin
3. Подготовьте программу, которая выведет только книги заданного автора. Pro. Power. Point. Ru new (Result); program task 4_18_3; Result : = item. List. New Result^. book. Data. title : = title; Type (title, author, count, price, place, next); book = record // Структура для хранения. Result^. book. Data. author : = author; end; данных о конкретной книге на складе Result^. book. Data. count : = count; title : string; Result^. book. Data. price : = price; function print. List. Item (item : p. Node) : author: string; Result^. book. Data. place : = place; p. Node; count : word; Result^. next : = next; begin price : longword; end; writeln(item^. book. Data. title, ', ', item^. book place : word; Data. price*item^. book. Data. count); end; function print. List. Item. Author (item : result : = item^. next; p. Node = ^List. Node; // Общая структура p. Node) : end; для организации учета склада p. Node; List. Node = record begin var next : p. Node; if item^. book. Data. author='Калинин head : p. Node; book. Data : book; И. А. , Самылкина Н. Н. ' then answ : char; end; writeln(item^. book. Data. author, ', ', item^. bobegin // Функция-итератор, подробно ok. Data. title, ', ', item^. book. Data. price); // Создание списка рассмотренная в задачнике result : = item^. next; head : = item. List. New ('Информатика iterate = function( item : p. Node): p. Node; end; 10', 'Калинин И. А. , Самылкина procedure iterator. List(start : p. Node; Н. Н. ', 10, 210, 1, nil); iterate. Function : iterate); // Ввод данных о книге с клавиатуры head : = item. List. New ('Информатика var function item. List. Keyboard (next : p. Node) 11', 'Калинин И. А. , Самылкина current : p. Node; Н. Н. ', 10, 180, 1, head); begin var repeat current : = start; title, author: string; write('Желаете ввести новую repeat count : word; книгу? (д/н)'); current: =iterate. Function(current); price : longword; readln(answ); until current = nil; place : word; if answ = 'д' then end; begin head : = item. List. Keyboard(head); // Добавление элемента в список write ('Введите название==>'); until answ <> 'д'; function item. List. New (title : string; readln(title); write. Ln('Книги искомого автора(ов): '); author: string; count : word; write ('Введите автора==>'); iterator. List(head, print. List. Item. Author); price : longword; readln(author); end. place : word; write ('Введите количество==>'); next : PNode): p. Node; readln(count); write ('Введите цену==>'); readln(price); begin write ('Введите место==>'); readln(place);
4*. Опишите структуру, которая позволит вводить данные о нескольких авторах и их книгах (неизвестно заранее, сколько их будет), а также по желанию пользователя дополнять описание книг атрибутами (например, ключевыми словами). //Универсальная структура хранения данных. До 65535 типов атрибутов. p. Attribute = ^attribute; attribute = record; next. Attribute : p. Attribute; attribute. Type : word; //Тип атрибута: 1 - автор, 2 - название, 3 - ключевое //слово и т. д. attribute. Number : longword; //Значение атрибута - число attribute. String : longword; //Значение атрибута - строка end; p. Book = ^Book. Universal; book. Universal = record //Книга, обладающая любым кол-вом атрибутов next : p. Book; attribute. List : p. Attribute; end; Примечания: для удобства необходимо оговорить нумерацию атрибутов (например, составить отдельную таблицу соответствия). Некоторые атрибуты могут встречаться несколько раз. *Требуется только описать структуру, а не программу. Pro. Power. Point. Ru
5. Опишите структуру данных, которая может быть использована для определения растения по наличию или отсутствию признаков (т. е. признак либо есть, либо нет). Ответом будет построение двоичного дерева, описанного в учебнике и рассмотренного здесь ранее. p. Binary. Node = ^Binary. Tree. Node; //необходимая структура Binary. Tree. Node = record left, right : p. Node; //Правая и левая ветви – записи. query. Text : string; //Содержат текстовое описание признаков. end; *Требуется только описать структуру, а не программу. Pro. Power. Point. Ru
6. Напишите программу, определяющую растение заданного семейства по стандартной определительной карте (например, крестоцветное). program task 4_18_6; type p. Node = ^Tree. Node; Tree. Node = record left, right: p. Node; left. Text, right. Text: string; end; function item. List. New(left. Text: string): p. Node; begin new(Result); Result^. left. Text : = left. Text; Result^. left : = nil; Result^. right : = nil; end; procedure info. Node(current: p. Node); var left. Text, right. Text: string; begin left. Text : = 'Споранхии есть. '; current^. left. Text : = left. Text; right. Text : = 'Споранхий нет. '; current^. right. Text : = right. Text; left. Text : = 'Зрелый лист. '; current^. left : = item. List. New(left. Text); right. Text : = 'Молодой лист. '; current^. right : = item. List. New(right. Text); end; Pro. Power. Point. Ru var answ: char; head, current: p. Node; begin head : = item. List. New('Что-то живое'); current : = head; info. Node(current); begin writeln('Вариант 1: ', current^. left. Text); writeln('Вариант 2: ', current^. right. Text); writeln('Выберите вариант 1 или 2 '); readln(answ); if answ = '1' then current : = current^. left else current : = current^. right; writeln('У нас есть только один вариант: ', current^. left. Text); end.
7*. Напишите программу, которая позволит расширить карту. program task 4_18_7; type p. Node = ^Tree. Node; Tree. Node = record left, right: p. Node; left. Text, right. Text: string; end; function item. List. New(left. Text: string): p. Node; begin new(Result); Result^. left. Text : = left. Text; Result^. left : = nil; Result^. right : = nil; end; Pro. Power. Point. Ru procedure new. Node(current: p. Node); var left. Text, right. Text: string; answ: char; begin writeln('Ввведите признак первого варианта '); readln(left. Text); current^. left. Text : = left. Text; writeln('Ввведите признак второго варианта '); readln(right. Text); current^. right. Text : = right. Text; writeln('Ввведите вывод по первому варианту '); readln(left. Text); current^. left : = item. List. New(left. Text); writeln('Ввведите вывод по второму writeln('У нас есть только один варианту '); вариант: ', current^. left. Text); readln(right. Text); writeln('Желаете добавить current^. right : = item. List. New(right. Text); ветвление? (д/н)'); readln(answ); end; if answ = 'д' then new. Node(current); var end; answ: char; end; head, current: p. Node; writeln('Желаете повторить определение? (д/н)'); begin readln(answ); head : = item. List. New('Что-то живое'); until answ = 'н'; current : = head; end. repeat while current <> nil do begin if current^. left. Text <> '' then writeln('Вариант 1: ', current^. left. Text); if current^. left. Text <> '' then writeln('Вариант 2: ', current^. right. Text); if (current^. left <> nil) and (current^. right <> nil) then begin writeln('Выберите вариант 1 или 2 '); readln(answ); if answ = '1' then current : = current^. left else current : = current^. right; end else begin


